gpt4 book ai didi

C++ std::string 初始化性能更好(汇编)

转载 作者:行者123 更新时间:2023-12-01 22:28:23 26 4
gpt4 key购买 nike

我正在使用 www.godbolt.org 来检查哪些代码会生成更好的汇编代码,但我无法理解为什么这两种不同的方法会生成不同的结果(在汇编命令中)。

第一种方法是声明一个字符串,然后设置一个值:

#include <string>
int foo() {
std::string a;
a = "abcdef";
return a.size();
}

在我的 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

所以,我想象如果我在声明中初始化字符串,输出程序集会更短:

int bar() {
std::string a {"abcdef"};
return a.size();
}

确实如此:

bar():
mov eax, 6
ret

为什么会有如此巨大的差异?是什么阻止 gcc 优化第一个版本,类似于第二个版本?

godbolt link

最佳答案

这只是一个猜测:

operator=具有强大的异常保证;这意味着:

If an exception is thrown for any reason, this function has no effect (strong exception guarantee). (since C++11)

(source)

因此,虽然构造函数可以将对象保留为它喜欢的任何状态,但 operator= 需要确保该对象与以前相同;我怀疑这就是为什么调用操作符删除(以清理可能分配的内存)。

关于C++ std::string 初始化性能更好(汇编),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59328310/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com