A couple of thoughts/queries.

Daniel Keep daniel.keep.lists at gmail.com
Sat Dec 8 02:56:50 PST 2007



Walter Bright wrote:
> Robby wrote:
>> Anyways, what I'm in hopes of finding is a way to tell the compiler
>> that I never want null, ever. I want an instance of the class and
>> that's that. The whole idea of taking every lil runtime hit for
>> checking  and the code cruft for writing it when in fact it's
>> something that seems to be easy for a compiler to do the work for me.
> 
> The hardware will do the check for null pointer for you every time you
> do a dereference.

<summary>

Non-nullable types != null deref exceptions.
Non-nullable types > null deref exceptions.
Non-nullable types > contracts.

</summary>

<rant>

That's not the point.  Null dereference errors aren't all that helpful.
 They tell you that something's gone wrong, but they don't tell you *why*.

Let's pretend for a moment that appending '@' to an object type makes it
a non-nullable type.  For example:

    Object@ o = null;

That would be a *compile-time error* since Object at s cannot be null.  It
also means that (in the general case) this won't work:

    Object o1 = new Object;
    Object@ o2 = o1;

That's because o1 could possibly contain a null.  So in order to do
this, you'd have to check that o1 is not null, and then cast.  Heck, the
compiler could even do that for you:

    Object@ o2 = cast(@) o1

Why is this better than a null dereference exception?  Because it will
throw the exception when you try to *introduce the null* into your
program's state, *not* when you try to use it.  Normally, all a null
dereference tells you is that somewhere along the line, you screwed up.
 This tells you *when* you screw up.

What's more, this makes code cleaner, easier to check, and faster.
Instead of having this all over the place:

    // the_object is a parameter, and could be null, so we'd best check
    // it!  We can't assert directly or the check will be elided in
    // -release builds.
    if( the_object is null ) assert(false);

...we need only check exactly once: where we introduce the object.
After that, there's zero runtime cost, since we've already guaranteed
that the reference is not null.  This is unlike contracts and invariants
which exact an overhead, not to mention the fact that you can always
either forget to write the assertion, or write it incorrectly.

Tim Sweeny (the lead programmer at Epic) once commented that the
majority of bugs in the Unreal engine were caused by null dereferences;
they knew the bugs were there, they just couldn't work out where the
nulls were coming from.  He said he'd kill to have non-nullable objects
in C++. [1]

This is something I've wanted for ages [2], if only for all the checks
it would let me not write.  I understand that there are lots of things
people want you to implement, and you can't fit them all in.  But don't
mistake this for null dereference exceptions.

	-- Daniel

[1] I'm recalling from memory; too tired to go tracking down the paper
itself.  Something about the next big programming language for games.
Incidentally, he put his money on a Haskell-style language with C-style
syntax.  And non-nullable types. :P

[2] Actually, what I *really* want is some form of type constraints.
Something like:

    alias real:{$ != 0 && $ == $} real_not_zero_or_nan;

    Assuming '$' means "current value".  At the moment, the best tool we
have for this is, unfortunately, Hungarian notation (apps Hungarian, not
that pointless system Hungarian.)

</rant>



More information about the Digitalmars-d mailing list