On Sunday, 3 November 2013 at 15:38:30 UTC, Luís Marques wrote:
Hi,

Most of the time my D code has been high-level, so I had never considered the following issue. Imagine you have a struct A as a member of a class/struct X (here a struct, to ensure the dtor is called):

    struct A
    {
        int v;

        this(int v)
        {
            this.v = v*2;
        }

        ~this()
        {
            writefln("~A(%d)", v);
        }
    }

    struct X
    {
        A a;

        this(int v)
        {
            a = A(v);
            writeln("-");
        }
    }

    void main()
    {
        X x = X(42);
    }

Output:

    ~A(0)
    -
    ~A(84)

That is, because we don't have C++'s colon initialization syntax, we are paying the cost of initializing (and then destroying) X.a before we assign to it with "a = A(v)" in X's ctor. This seems to be the case even with @disable A.this(), which here does not seem to do anything (does not prevent the default/implicit initialization of X.a, before it is assigned A(v) ).

If C++ distinguishes between initialization and assignment to avoid this issue, is there a reason why D can avoid making the distinction? That is a performance issue. How about correctness? For instance:

    struct A
    {
        void* mem;

        @disable this();

        this(int v)
        {
            mem = malloc(v);
        }

        ~this()
        {
            free(mem);
        }
    }

Now we can't have an A as a member of X? (it would free a null pointer)

How have you solved these cases? Do you change it to a PIMPL? What if that's not desirable? What if you don't want to break encapsulation / cleanliness too much? Etc. Is there a good general solution for this issue?

for actual version of dmd, you can use this trick :)

struct A
{
        int v;
        
        void opAssign(int v) {
                this.v = v;
        }
        
        static int opCall(int v) {
                return v * 2;
        }
        
        ~this()
        {
                writefln("~A(%d)", v);
        }
}

Reply via email to