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