[Issue 7353] NRVO not properly working with inferred return type

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Feb 15 09:16:28 PST 2012


http://d.puremagic.com/issues/show_bug.cgi?id=7353



--- Comment #4 from Kenji Hara <k.hara.pg at gmail.com> 2012-02-15 09:16:26 PST ---
(In reply to comment #3)
> You're right. The third one is an inlining problem.
> 
> But there's a different thing I'm now confused about. Why is postblit called
> after all?
> It's assignment to t, not construction.
> 
> See the docs:
> struct S { ... }
> S s;      // default construction of s
> S t = s;  // t is copy-constructed from s => this(this)
> t = s;    // t is assigned from s => opAssign

The assignment to t does not call postblit. Because the built-in opAssign is
implemented as 'swap and destroy' due to never create any unnecessary copy on
assignment.

First of all, S has postblit, then dmd creates implicit built-in opAssing like
follows:
ref S opAssign(S rhs) {  // rhs receives rvalue, not lvalue
  swap(this, rhs);
  return this;
  // rhs is destroyed the end of opAssign function scope
}

Next, the code sequence with explanation:
{
    S s = S(1);   // prints new: 0
    S t = S(1);   // prints new: 1
    t = s.save1();
    // is translated to t.opAssign(s.save1())
    // inside save1():
        S s = this;   // prints copy 2
        return s;     // s is moved out by nrvo
    // t.opAssign receives moved value, so is never copied
    // inside t.opAssign():
        // this (this.i==1) is swapped with rhs, and destroyed
        // prints del 1
    // s.i == 0
    // t.i == 2
    // destroyed local variables in reverse order
    // prints del 2
    // prints el 1
}

Last, the postblit call runs only once.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list