この単純なスニペットをコンパイルしました。
#include <iostream>
#include <string>
std::string foo()
{
return std::string("bar");
}
int main()
{
std::string test = foo();
std::cout << test << std::endl;
return 0;
}
最適化を使用し-O2
て、2つのstd::stringオブジェクトが作成されていることを検出するだけです。バイナリをダンプすると、objdumpはそれ~basic_string
が2回呼び出されたことを示します。
0000000000400900 <main>:
400900: 53 push %rbx
400901: 48 83 ec 10 sub $0x10,%rsp
400905: 48 89 e7 mov %rsp,%rdi
400908: e8 73 01 00 00 callq 400a80 <foo()>
40090d: 48 89 e6 mov %rsp,%rsi
400910: bf 80 10 60 00 mov $0x601080,%edi
400915: e8 a6 ff ff ff callq 4008c0 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@plt>
40091a: 48 89 c7 mov %rax,%rdi
40091d: e8 ae ff ff ff callq 4008d0 <std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)@plt>
400922: 48 89 e7 mov %rsp,%rdi
400925: e8 76 ff ff ff callq 4008a0 <std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@plt>
40092a: 48 83 c4 10 add $0x10,%rsp
40092e: 31 c0 xor %eax,%eax
400930: 5b pop %rbx
400931: c3 retq
400932: 48 89 c3 mov %rax,%rbx
400935: 48 89 e7 mov %rsp,%rdi
400938: e8 63 ff ff ff callq 4008a0 <std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@plt>
40093d: 48 89 df mov %rbx,%rdi
400940: e8 ab ff ff ff callq 4008f0 <_Unwind_Resume@plt>
400945: 66 66 2e 0f 1f 84 00 data32 nopw %cs:0x0(%rax,%rax,1)
40094c: 00 00 00 00
本当に必要なオブジェクトは1つだけなのでfoo()
、右辺値参照を使用して返される値をキャプチャすることを考えました。そのため、コード行をstd::string && test = foo();
Weirdlyに変更しましたが、objdumpにはまだ呼び出された2つのデストラクタが表示されます。誰かが私に理由を説明できますか?