我刚刚编译了这个简单的片段:
#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
优化,却发现正在创建两个 std::string 对象。当我转储二进制文件时,objdump 显示它~basic_string
被调用了两次。
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
因为我真的只需要一个对象,所以我考虑foo()
使用右值引用来捕获返回的值。所以我把这行代码std::string && test = foo();
改成 Weirdly,objdump 仍然显示调用了两个析构函数。谁能解释我为什么?