Null references (oh no, not again!)

Ary Borenszweig ary at esperanto.org.ar
Thu Mar 5 02:08:39 PST 2009


Walter Bright escribió:
> Ary Borenszweig wrote:
>> Walter Bright escribió:
>>> Ary Borenszweig wrote:
>>>> Walter Bright escribió:
>>>>> Ary Borenszweig wrote:
>>>>>> It's not like that. They don't require you to initialize a 
>>>>>> variable in it's initializer, but just before you read it for the 
>>>>>> fist time. That's very different.
>>>>>
>>>>> The only way to do that 100% reliably is to instrument the running 
>>>>> code.
>>>>
>>>> Java does it on compile time.
>>>
>>> Java is a severely constrained language. Even so, how does it do with 
>>> this:
>>>
>>> Foo f;
>>> if (x < 1) f = new Foo(1);
>>> else if (x >= 1) f = new Foo(2);
>>> f.member();
>>
>> Whenever there are branches in code and a variable still doesn't have 
>> a value at that point:
>>  - if all branches assign a value to that variable, from now on the 
>> variable has a value
>>  - if not, at then end of the branches the variable still doesn't have 
>> a value
> 
> That rule gets the wrong answer in the above case. Consider that in 
> order to get where you want to go with this, the flow analysis has to 
> always work, not most of the time work. Otherwise you get bug reports 
> with phrases like "seems to", "sometimes", "somehow", "I can't figure it 
> out", "I can't reproduce the problem", etc.
> 
> Here's another lovely case:
> 
> Foo f;
> if (x < 1) f = new Foo();
> ... lots of code ...
> if (x < 1) f.member();
> 
> The code is quite correct and bug-free, but flow analysis will tell you 
> that f in f.member() is "possibly uninitialized".

That's exactly the example of a code with a possible bug that'll get an 
null pointer access. Imagine in "... lots of code ..." you use f and the 
compiler complains. But you are sure "x < 1" will be true! Then you need 
to add an else and some assert(false) or throw an exception and that's it.

If the second condition is "if (x >= 1)" and in the next line you use f, 
then yes, you are definitely sure that "f" is initialized if you didn't 
touch "x" in "... lots of code ...". Well... not really, if some other 
thread changed "x" in the middle of the code, then you are not really 
sure about that. So again, it's an error.

If you are really, really sure that this won't happen, you do:

Foo f = null;

and that's it. You make the compiler help you only when you want it to, 
and that'll be most of the time.

The same goes with:

Foo f;
bar(&f);

If you are sure that bar will assign a value to f if it doesn't have 
one, go ahead and initialize "f" with null.



More information about the Digitalmars-d mailing list