Scope of temporaries as function arguments

Maxim Fomin maxim at maxim-fomin.ru
Fri Jun 28 08:33:39 PDT 2013


On Friday, 28 June 2013 at 15:17:12 UTC, monarch_dodra wrote:
>
> Should I have expected a different behavior?

import std.stdio;

int callme()
{
    throw new Exception("");
}

struct S
{
    int i = 0;
     this(int i){this.i = i; writeln("constructing: ", i);}
     this(this){writeln("postbliting: ", i);}
     ~this(){writeln("destroying: ", i);}
}

void foo(S s, int i)
{
    s.i = 2;
}

void main()
{
    S s = S(1);
    foo(s, callme());
}

Destructor for copied object is not called because it is placed 
in foo(). Before calling foo(), dmd makes a copy of main.s, calls 
postblit, then puts code to invoke callme() and code to invoke 
foo(). Since callme() throws, foo() is not called and destructor 
placed in foo() is also not called. A struct copy escapes 
destructor.

Now, if you try fix this by putting dtor for copy not in foo(), 
but in main immediately after foo() invocation, you will have a 
problem because destructor would get S(1) object while it should 
destroy S(2). Any modification made in foo() is lost. This can be 
possible fixed by passing copy by reference which would probably 
create new ABI problems.


More information about the Digitalmars-d-learn mailing list