www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 7353] New: NRVO not properly working with inferred return type

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353

           Summary: NRVO not properly working with inferred return type
           Product: D
           Version: D1 & D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: performance
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: mrmocool gmx.de



import std.stdio;
struct S
{
    static uint ci = 0;
    uint i;

    this(int x)
    {
        i = ci++;
        writeln("new: ", i);
    }

    this(this)
    {
        i = ci++;
        writeln("copy ", i);
    }

    ~this()
    {
        writeln("del ", i);
    }

    S save1() // produces 2 copies in total
    {
        S s = this;
        return s;
    }

    auto save2() // produces 3 copies in total
    {
        S s = this;
        return s;
        pragma(msg, typeof(return));
    }

    S save3()
    {
        return this;
    }
}

void main()
{
    {
    S s = S(1);
    S t = S(1);

    t = s.save1();
    }

    writeln("-");
    S.ci = 0;
    {
    S s = S(1);
    S t = S(1);
    t = s.save2();
    }

    writeln("-");
    S.ci = 0;
    {
    S s = S(1);
    S t = S(1);
    t = s.save3();
    }
}


$ dmd -run test.d
//or dmd -release -run test.d
//or dmd -release -O -run test.d
S
new: 0
new: 1
copy 2
del 1
del 2
del 0
-
new: 0
new: 1
copy 2
copy 3
del 2
del 1
del 3
del 0
-
new: 0
new: 1
copy 2
del 1
del 2
del 0

$ dmd -release -O -inline -run test.d
S
new: 0
new: 1
copy 2
del 1
del 2
del 0
-
new: 0
new: 1
copy 2
copy 3
del 2
del 1
del 3
del 0
-
new: 0
new: 1
del 1
del 0
del 0

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 23 2012
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353


Trass3r <mrmocool gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code



Hmm that last one even looks like a wrong-code bug, 0 is deleted twice.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 23 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353


Lionello Lunesu <lio+bugzilla lunesu.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lio+bugzilla lunesu.com
           Severity|normal                      |critical


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 12 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|wrong-code                  |pull
            Version|D1 & D2                     |D2



Postblit is only in D2 spec, so this is not 'D1 & d2' issue.

I think save3() is inlining problem, then I've separated it as bug 7506.
Therefore I remove 'wrong-code' keyword.

----

Current compiler implementation disables nrvo with auto function.
I've post a pull to fix it.

https://github.com/D-Programming-Language/dmd/pull/722

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 15 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353




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

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 15 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353





 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: -------
Feb 15 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353




Ok, so in essence the postblit is the one called by 'S s = this;' in save1.
But what about save3?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 15 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353




Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/02ecef1cea5dea4f78bafb7533c896d0d9b07816


Issue 7353 - NRVO not properly working with inferred return type

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 17 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7353


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla digitalmars.com
         Resolution|                            |FIXED


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