Coverity tool

Michel Fortin michel.fortin at michelf.com
Wed Feb 10 19:16:32 PST 2010


On 2010-02-10 17:29:09 -0500, Walter Bright <newshound1 at digitalmars.com> said:

> retard wrote:
>> What exactly is the cost here? The non-nullability invariant can be 
>> checked on compile time. It incurs no runtime overhead. Also the 
>> notation can be quite terse, as we have seen in Other Languages(tm).
> 
> If you want, you can create a template NonNullable that wraps an 
> existing type, and try that out.

Just did that yesterday. It's probably not what most people expect 
though: it doesn't do static checking. But at least it catches null 
assignments early, before the null value breaks something elsewhere in 
the program. For your enjoyment:

/**
 Struct to make object references and pointers unable to accept a null value.
 The initial value is still null, but after the first assignment the value can
 never become null again. Attempting to assign null will throw an
 IllegalNullAssignment error.
 */
struct NonNullable(T) {
	private T _nonNullableValue;
	alias _getNonNullableValue this;
	
	this(T value) {
		opAssign(value);
	}
	this(NonNullable!T value) {
		// FIXME: Not polymorphic
		opAssign(value);
	}
	
	void opAssign(V, string file = __FILE__, int line = __LINE__)(V newValue) {
		if (isNull(newValue))
			IllegalNullAssignment.bailOut(file, line, "Attempt to assign null to "
										  "non-nullable " ~ T.stringof ~ ".");
		_nonNullableValue = newValue;
	}
	
	T _getNonNullableValue() {
		assert(_nonNullableValue, "Attempt to access uninitialized 
non-nullable " ~ T.stringof ~ ".");
		return _nonNullableValue;
	}
	
	private {
		bool isNull(T)(T value) if (__traits(compiles, value._nonNullableValue)) {
			return isNull(value._nonNullableValue);
		}
		bool isNull(T)(T value) if (__traits(compiles, value is null)) {
			return value is null;
		}
	}
}


/**
 Error thrown when attempting to assign a null value to a non-nullable.
 */
class IllegalNullAssignment : Error {
	this(string message) {
		super(message);
	}
	
	private static void bailOut(string file, int line, in char[] msg) {
		throw new IllegalNullAssignment(text(file, '(', line, "): ", msg));
	}
}


unittest {
	NonNullable!Object o;
	NonNullable!ClassInfo o2 = o.classinfo;
	NonNullable!TypeInfo o3;
	//NonNullable!Object o4 = o2; // FIXME: polymorphic NonNullable
	o = new Object;
	o = o2;
	try {
		o = o3; // should throw
		o.toString();
		assert(0, "prior assignment should have thrown");
	} catch (IllegalNullAssignment e) {
		// ok, error thrown.
	}
}



-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/




More information about the Digitalmars-d mailing list