Null references redux

downs default_357-line at yahoo.de
Sun Sep 27 04:12:51 PDT 2009


Jeremie Pelletier wrote:
> Christopher Wright wrote:
>> Jeremie Pelletier wrote:
>>> What if using 'Object obj;' raises a warning "unitialized variable"
>>> and makes everyone wanting non-null references happy, and 'Object obj
>>> = null;' raises no warning and makes everyone wanting to keep the
>>> current system (all two of us!) happy.
>>>
>>> I believe it's a fair compromise.
>>
>> It's a large improvement, but only for local variables. If your
>> segfault has to do with a local variable, unless your function is
>> monstrously large, it should be easy to fix, without changing the type
>> system.
>>
>> The larger use case is when you have an aggregate member that cannot
>> be null. This can be solved via contracts, but they are tedious to
>> write and ubiquitous.
> 
> But how would you enforce a nonnull type over an aggregate in the first
> place? If you can, you could also apply the same initializer semantics I
> suggested earlier.
> 
> Look at this for example:
> 
> struct A {
>     Object cannotBeNull;
> }
> 
> void main() {
>     A* a = new A;
> }
> 
> Memory gets initialized to zero, and you have a broken non-null type.
> You could have the compiler throw an error here, but the compiler cannot
> possibly know about all data creation methods such as malloc, calloc or
> any other external allocator.
> 
> You could even do something like:
> 
> Object* foo = calloc(Object.sizeof);
> 
> and the compiler would let you dereference foo resulting in yet another
> broken nonnull variable.
> 
> Non-nulls are a cute idea when you have a type system that is much
> stricter than D's, but there are just way too many workarounds to make
> it crash in D.

"Here are some cases you haven't mentioned yet. This proves that the compiler can't possibly be smart enough. "

Yeeeeeah.

In the above case, why not implicitly put the cannotBeNull check into the struct invariant? That's where it belongs, imho.

Regarding your example, it's calloc(size_t.sizeof). And a) we probably can't catch that case except with in/out null checks on every method, but then again, how often have you done that? I don't think it's relevant enough to be relevant to this thread. :)



More information about the Digitalmars-d mailing list