gpt4 book ai didi

c++ - 当我使用直接初始化与 std::initializer_list 时的不同指令

转载 作者:行者123 更新时间:2023-12-02 01:52:05 25 4
gpt4 key购买 nike

我正在尝试各种初始化方法,并评估它们为各种用例提供​​的开发人员体验及其性能影响。在此过程中,我编写了两段代码,一段是直接初始化,另一段是初始化列表。

直接:

class C {
public:
char* x;

C() : x(new char[10] {'0','1'}) {}
};

C c;

初始化列表:

#include <utility>
#include <algorithm>

class C {
public:
char* x;

C(std::initializer_list<char> il) {
x = new char[10];
std::copy(il.begin(), il.end(), x);
}
};

C c = {'0','1'};

我在期待std::initializer_list生成相同的程序集,虽然我可以理解为什么它可能会更糟(看起来更复杂),但如果它实际上更糟,我会在这里问一个非常不同的问题。想象一下,当我看到它用更少的指令生成更好代码时,我有多惊讶!

使用上述片段链接到 godbolt - https://godbolt.org/z/i3XZ_K

直接:

_GLOBAL__sub_I_c:
sub rsp, 8
mov edi, 10
call operator new[](unsigned long)
mov edx, 12592
mov WORD PTR [rax], dx
mov QWORD PTR [rax+2], 0
mov QWORD PTR c[rip], rax
add rsp, 8
ret
c:
.zero 8

初始化列表:

_GLOBAL__sub_I_c:
sub rsp, 8
mov edi, 10
call operator new[](unsigned long)
mov edx, 12592
mov QWORD PTR c[rip], rax
mov WORD PTR [rax], dx
add rsp, 8
ret
c:
.zero 8

除了额外的 mov QWORD PTR [rax+2], 0 之外,程序集几乎相同乍一看似乎是用空字符终止 char 数组的指令。但是,IIRC 仅字符串文字(如 "01" )自动以空字符终止,而不是字符数组文字。

如果能深入了解生成的代码为何不同以及我可以做些什么(如果可能的话)来使直接案例变得更好,我将不胜感激。

另外,我是 x86 汇编方面的菜鸟,所以如果我遗漏了一些明显的东西,请告诉我。

编辑:如果我添加更多字符,情况只会变得更糟 - https://godbolt.org/z/e8Gys_

最佳答案

两个示例代码片段的效果不同。

new char[10] {'0','1'}

此聚合初始化新的 char数组,这意味着数组中所有在大括号括起来的初始化器列表中没有给出初始化器的元素都被初始化为零。

x = new char[10];

这不会将新数组的任何元素设置为任何值,并且

std::copy(il.begin(), il.end(), x);

仅设置 std::initializer_list 中实际指定的元素.

因此,在第一个版本中,编译器必须保证所有没有指定初始值设定项的元素都设置为零,而在第二个版本中,编译器可以保持这些值不变。

无法直接在 new 表达式中部分初始化数组。但是第二个示例的行为的明显再现将类似于

C() : x(new char[10]) {
constexpr char t[]{'0','1'};
std::copy(std::begin(t), std::end(t), x);
}

不过,实际上,您不应该使用 new无论如何直接。而是使用std::vector<char> , std::array<char, 10> , std::stringstd::unique_ptr<char[]>取决于具体用例。所有这些都避免了 new 的生命周期问题。会导致。

关于c++ - 当我使用直接初始化与 std::initializer_list 时的不同指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60724094/

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