http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60367
--- Comment #5 from rob.desbois at gmail dot com --- The following is a side-by-side diff of the disassembly of the incorrect version vs. a correct version (defaulting the parameter with = foo{}). The object foo has a single member of type char initialized in default, move, and copy ctors. incorrect version | correct version -------------------------------------------|----------------------------------- push %rbp push %rbp mov %rsp,%rbp mov %rsp,%rbp push %rbx push %rbx sub $0x28,%rsp | sub $0x18,%rsp lea -0x11(%rbp),%rax lea -0x11(%rbp),%rax mov %rax,%rdi mov %rax,%rdi callq 0x400bbe <_ZN3fooC2Ev> | callq 0x400bb8 <_ZN3fooC2Ev> movzbl -0x11(%rbp),%eax | lea -0x11(%rbp),%rax mov %al,-0x30(%rbp) < lea -0x30(%rbp),%rax < mov %rax,%rdi mov %rax,%rdi callq 0x4009f0 <_Z6test_a3foo> | callq 0x400a50 <_Z6test_b3foo> lea -0x11(%rbp),%rax lea -0x11(%rbp),%rax mov %rax,%rdi mov %rax,%rdi callq 0x400bfe <_ZN3fooD2Ev> | callq 0x400bf8 <_ZN3fooD2Ev> mov $0x0,%eax mov $0x0,%eax jmp 0x400b65 <main+85> | jmp 0x400b5e <main+78> mov %rax,%rbx mov %rax,%rbx lea -0x11(%rbp),%rax lea -0x11(%rbp),%rax mov %rax,%rdi mov %rax,%rdi callq 0x400bfe <_ZN3fooD2Ev> | callq 0x400bf8 <_ZN3fooD2Ev> mov %rbx,%rax mov %rbx,%rax mov %rax,%rdi mov %rax,%rdi callq 0x4008b0 <_Unwind_Resume@plt> callq 0x4008b0 <_Unwind_Resume@plt> add $0x28,%rsp | add $0x18,%rsp pop %rbx pop %rbx pop %rbp pop %rbp retq retq It does look like the incorrect version on the left could be bitwise-copying the default-constructed object. As an aside - both versions have a single constructor call but TWO destructor calls...