dereferencing null

Timon Gehr timon.gehr at gmx.ch
Wed Mar 7 16:39:03 PST 2012


On 03/08/2012 01:24 AM, Chad J wrote:
> On 03/07/2012 04:41 AM, Timon Gehr wrote:
>> On 03/07/2012 02:40 AM, Chad J wrote:
>>> But to initialize non-null fields, I suspect we would need to be able to
>>> do stuff like this:
>>>
>>> class Foo
>>> {
>>> int dummy;
>>> }
>>>
>>> class Bar
>>> {
>>> Foo foo = new Foo();
>>>
>>> this() { foo.dummy = 5; }
>>> }
>>>
>>> Which would be lowered by the compiler into this:
>>>
>>> class Bar
>>> {
>>> // Assume we've already checked for bogus assignments.
>>> // It is now safe to make this nullable.
>>> Nullable!(Foo) foo;
>>>
>>> this()
>>> {
>>> // Member initialization is done first.
>>> foo = new Foo();
>>>
>>> // Then programmer-supplied ctor code runs after.
>>> foo.dummy = 5;
>>> }
>>> }
>>>
>>> I remember C# being able to do this. I never understood why D doesn't
>>> allow this. Without it, I have to repeat myself a lot, and that is just
>>> wrong ;).]
>>
>> It is not sufficient.
>>
>> class Bar{
>> Foo foo = new Foo(this);
>> void method(){...}
>> }
>> class Foo{
>> this(Bar bar){bar.foo.method();}
>> }
>
> Lowered it a bit to try to compile, because it seems Foo doesn't have a
> method() :
>
> import std.stdio;
>
> class Bar{
> Foo foo;
> this()
> {
> foo = new Foo(this);
> }
> void method(){ writefln("poo"); }
> }
> class Foo{
> this(Bar bar){bar.foo.method();}
> }
>
> void main()
> {
> }
>
> And, it doesn't:
> main.d(12): Error: no property 'method' for type 'main.Foo'
>

Just move the method from Bar to Foo.

import std.stdio;

class Bar{
     Foo foo;
     this()
     {
         foo = new Foo(this);
     }
}
class Foo{
     this(Bar bar){bar.foo.method();}
     void method(){ writefln("poo"); }
}

void main()
{
     auto bar = new Bar;
}



> Though, more to the point:
> I would probably forbid "Foo foo = new Foo(this);". The design that
> leads to this is creating circular dependencies, which is usually bad to
> begin with.

Circular object references are often justified.

> Would we lose much of value?

Well this would amount to forbidding escaping an object from its 
constructor, as well as forbidding calling any member functions from the 
constructor. Also, if you *need* to create a circular structure, you'd 
have to use sentinel objects. Those are worse than null.



More information about the Digitalmars-d mailing list