Initialization vs Assignment

Kozzi kozzi11 at gmail.com
Sun Nov 3 08:28:38 PST 2013


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);
	}
}


More information about the Digitalmars-d mailing list