Null references redux

Denis Koroskin 2korden at gmail.com
Sat Sep 26 15:15:33 PDT 2009


On Sun, 27 Sep 2009 01:59:45 +0400, Jeremie Pelletier <jeremiep at gmail.com>  
wrote:

> Jarrett Billingsley wrote:
>> On Sat, Sep 26, 2009 at 5:29 PM, Jeremie Pelletier <jeremiep at gmail.com>  
>> wrote:
>>
>>> I actually side with Walter here. I much prefer my programs to crash on
>>> using a null reference and fix the issue than add runtime overhead  
>>> that does
>>> the same thing. In most cases a simple backtrace is enough to pinpoint  
>>> the
>>> location of the bug.
>>  There is NO RUNTIME OVERHEAD in implementing nonnull reference types.
>> None. It's handled entirely by the type system. Can we please move
>> past this?
>>
>>> Null references are useful to implement optional arguments without any
>>> overhead by an Optional!T wrapper. If you disallow null references what
>>> would "Object foo;" initialize to then?
>>  It wouldn't. The compiler wouldn't allow it. It would force you to
>> initialize it. That is the entire point of nonnull references.
>
> How would you do this then?
>
> void foo(int a) {
> 	Object foo;
> 	if(a == 1) foo = new Object1;
> 	else if(a == 2) foo = Object2;
> 	else foo = Object3;
> 	foo.doSomething();
> }
>

Let's consider the following example, first:

void foo(int a) {
	Object foo;
	if (a == 1) foo = Object1;
	else if(a == 2) foo = Object2;
	else if(a == 3) foo = Object3;

	foo.doSomething();
}

Do you agree that this program has a bug? It is buggy, because one of the  
paths skips "foo" variable initialization.

Now back to your question. My answer is that compiler should be smart  
enough to differentiate between the two cases and raise a compile-time  
error in a latter one. That's what C# compiler does: the first case  
successfully compiles while the second one doesn't.

Until then, non-nullable references are too hard to use to become useful,  
because you'll end up with a lot of initializer functions:

void foo(int a) {
	Object initializeFoo() {
		if (a == 1) return new Object1();
		if (a == 2) return new Object2();
		return new Object3();
         }

	Object foo = initializeFoo();
	foo.doSomething();
}

I actually believe the code is more clear that way, but there are cases  
when you can't do it (initialize a few variables, for example)



More information about the Digitalmars-d mailing list