我在玩 www.godbolt.org 来检查哪些代码会生成更好的汇编代码,但我不明白为什么这两种不同的方法会生成不同的结果(在汇编命令中)。
第一种方法是声明一个字符串,然后再设置一个值:
#include <string>
int foo() {
std::string a;
a = "abcdef";
return a.size();
}
Run Code Online (Sandbox Code Playgroud)
其中,在我的 gcc 7.4 ( -O3) 输出中:
.LC0:
.string "abcdef"
foo():
push rbp
mov r8d, 6
mov ecx, OFFSET FLAT:.LC0
xor edx, edx
push rbx
xor esi, esi
sub rsp, 40
lea rbx, [rsp+16]
mov rdi, rsp
mov BYTE PTR [rsp+16], 0
mov QWORD PTR [rsp], rbx
mov QWORD PTR [rsp+8], 0
call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long)
mov rdi, QWORD PTR [rsp]
mov rbp, QWORD PTR [rsp+8]
cmp rdi, rbx
je .L1
call operator delete(void*)
.L1:
add rsp, 40
mov eax, ebp
pop rbx
pop rbp
ret
mov rbp, rax
jmp .L3
foo() [clone .cold]:
.L3:
mov rdi, QWORD PTR [rsp]
cmp rdi, rbx
je .L4
call operator delete(void*)
.L4:
mov rdi, rbp
call _Unwind_Resume
Run Code Online (Sandbox Code Playgroud)
所以,我想象如果我在声明中初始化字符串,输出程序集会更短:
int bar() {
std::string a {"abcdef"};
return a.size();
}
Run Code Online (Sandbox Code Playgroud)
确实是这样:
bar():
mov eax, 6
ret
Run Code Online (Sandbox Code Playgroud)
为什么会有如此巨大的差异?是什么阻止 gcc 优化类似于第二个版本的第一个版本?