Non-nullable references, again
Daniel Keep
daniel.keep.lists at gmail.com
Tue Dec 30 21:37:56 PST 2008
dsimcha wrote:
>>> 50% of the bugs that people run into today, coding with C# in our
>>> platform, and the same is true of Java for that matter, are probably
>>> null reference exceptions.
>
> Yes, but even if this is accurate, it's misleading. Very seldom are null
> references difficult-to-find, time-consuming bugs. Most other things in D and
> other languages that are designed to prevent specific classes of bugs are designed
> to prevent extremely aggravating, hard to track down bugs.
>
> For example, GC was invented because tracking down memory leaks is a huge PITA.
> Bounds checking was invented because off-by-one errors can be subtle and hard to
> find. Null reference errors, on the other hand, manifest themselves in a
> predictable way (segfaults), and if you're using the safe memory model, i.e.
> bounds checking, no pointers, that's about the only thing a segfault could mean.
> Furthermore, null checking could be added to an implementation kind of like bounds
> checking without changing the language spec. I haven't made up my mind fully yet,
> but I question whether adding lots of complexity to the language to prevent a very
> easy to track down class of bugs, even if it's a common one, is justified.
I find this counterpoint to be a bit iffy. The problem with null
dereference problems isn't knowing that they're there: that's the easy
part. You helpfully get an exception to the face when that happens.
The hard part is figuring out *where* the problem originally occurred.
It's not when the exception is thrown that's the issue; it's the point
at which you placed a null reference in a slot where you shouldn't have.
Yes, we have invariants and contracts; but inevitably you're going to
forget one, and it's that one slip-up that's going to bite you in the rear.
One could use roughly the same argument for non-null references as for
const: you could document it, but documentation is inevitably wrong or
out of date. :P
That said, I wonder what's stopping us from implementing them today.
Last time I checked (admittedly, that was like a year ago) we didn't
have the compile-time magic necessary to completely and transparently
proxy any given object.
Ideally, we should be able to do this:
class Foo
{
void bar() { writefln("OH HAI WURLD!"); }
}
NonNull!(Foo) foo = new Foo;
foo.bar();
Foo baz = foo;
Off the top of my head, NonNull would require an opAssign,
opImplicitCast to the templated type, and a way to build a full proxy of
the underlying type.
It also just occured to me that this would probably break scope. Damn.
A nicer syntax would be appreciated, but probably isn't a requirement. :)
-- Daniel
More information about the Digitalmars-d
mailing list