7

test environment: vs 2008, debug mode

test code is:

// a demo for return value

class C
{
public:
    int value;
    int value2;
    int value3;

    //C(int v=0): value(v) {};
};

C getC(int v)
{
    C c1;

    return c1;
}



int main()
{
    C c1 = getC(10);

    return 0;
}

and the asm output is:

; 39   :    C c1 = getC(10);

push    10                  ; 0000000aH
lea eax, DWORD PTR $T2595[ebp]
push    eax
call    ?getC@@YA?AVC@@H@Z          ; getC
add esp, 8
mov ecx, DWORD PTR [eax]
mov DWORD PTR $T2594[ebp], ecx
mov edx, DWORD PTR [eax+4]
mov DWORD PTR $T2594[ebp+4], edx
mov eax, DWORD PTR [eax+8]
mov DWORD PTR $T2594[ebp+8], eax
mov ecx, DWORD PTR $T2594[ebp]
mov DWORD PTR _c1$[ebp], ecx
mov edx, DWORD PTR $T2594[ebp+4]
mov DWORD PTR _c1$[ebp+4], edx
mov eax, DWORD PTR $T2594[ebp+8]
mov DWORD PTR _c1$[ebp+8], eax

From the asm output, we can see the compile create 2 temporary object.

However, when I define the constructor as follow:

C(int v=0): value(v) {};

and recompiled the program, the asm output is become:

; 39   :    C c1 = getC(10);

push    10                  ; 0000000aH
lea eax, DWORD PTR _c1$[ebp]
push    eax
call    ?getC@@YA?AVC@@H@Z          ; getC
add esp, 8

Obviously, the compiler optimize the code, and my question is:

Why does adding the user-written constructor affect the generated assembly so much?

M.M
  • 138,810
  • 21
  • 208
  • 365
ajaxhe
  • 571
  • 1
  • 5
  • 13
  • The VC++ compiler does not perform [Copy Elision](http://en.wikipedia.org/wiki/Copy_elision) consistently. You might be seeing an example of that. – Jonathan Wakely Jul 29 '14 at 08:36
  • I have edited to use the term *user-written* instead of *explicit*, as the latter is a bit confusing since there is a keyword `explicit` for constructors (and this is not that) – M.M Jul 29 '14 at 08:45
  • 8
    I'd generally suggest not to read too much into the generated assembly code when using Debug. When Debug build is used, the compiler ensures it can perform step-by-step debugging; this, in turn, means optimisations can't always be used. If you want to look at the generated assembly, best do so in Release build. – MicroVirus Jul 29 '14 at 08:52
  • 1
    Before, class was POD. Afterward, not. – Yakk - Adam Nevraumont Aug 03 '14 at 18:09

1 Answers1

1

This question is about copy elision and return value optimization in C++.

I suggest you do not spend to much time on it because the assembly code generated depends on the compiler.

Copy elision is defined in the standard:

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization. This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

[...]

§12.8 [class.copy]

There is already a question you can refer on stackoverflow, see here.

Community
  • 1
  • 1