Null pointer dereferencing in D

John Colvin via Digitalmars-d digitalmars-d at puremagic.com
Sat Jun 14 08:41:09 PDT 2014


On Saturday, 14 June 2014 at 14:51:10 UTC, Dicebot wrote:
> On Saturday, 14 June 2014 at 13:38:40 UTC, Maxim Fomin wrote:
>>> Which is effectively a type system hole with @disable this :
>>>
>>> struct A { @disable this(); }
>>> auto a = A.init;
>>
>> Why this is a type hole if initializer is explicitly provided?
>>
>> The idea of disabled this() is to prevent default 
>> initialization,
>> not to reject potentially buggy one.
>
> Well consider imaginary NotNullable struct that uses "@disable 
> this()" to guarantee that instance of that struct always has 
> meaningful state. By using (NotNullable!T).init you can get 
> value of that type which is in fact null and pass it as an 
> argument to function that expects NotNullable to always be non 
> null. With no casts involved you have just circumvented 
> guarantees static type system was suppose to give.

Hole in the type system: yes
Necessarily a bad thing: no

Some data-types require runtime initialisation to be valid. By 
using .init you are explicitly circumventing any runtime 
initialisation. It's an explicit hole, just like cast.

It appears that it possible (in 2.065 at least) for a struct to 
provide it's own init, which can of course be

template init() { static assert(false); }

Is the ability to manually specify .init a bug or a feature? I 
feel like it's a bug.


I would like to see a logicalInit added to druntime/phobos and 
adopted where appropriate instead of .init

auto logicalInit(T)()
{
     static if(hasMember!(T, "logicalInit"))
     {
         return T.logicalInit;
     }
     else
     {
         return T.init;
     }
}

and then types can define their own logicalInit, whether it's 
just a static assert or something else. Perhaps it should be 
limited to compile-time values only to avoid it being a default 
constructor workaround.


More information about the Digitalmars-d mailing list