gpt4 book ai didi

c++ - 为什么 clang 不使用 NRVO 对此进行优化?

转载 作者:可可西里 更新时间:2023-11-01 18:17:14 31 4
gpt4 key购买 nike

我试图解释为什么一个相当不错的 C++ 11 编译器 (clang) 没有优化这段代码,并且想知道这里是否有人有意见。

#include <iostream>
#define SLOW

struct A {
A() {}
~A() { std::cout << "A d'tor\n"; }
A(const A&) { std::cout << "A copy\n"; }
A(A&&) { std::cout << "A move\n"; }
A &operator =(A) { std::cout << "A copy assignment\n"; return *this; }
};

struct B {
// Using move on a sink.
// Nice talk at Going Native 2013 by Sean Parent.
B(A foo) : a_(std::move(foo)) {}
A a_;
};

A MakeA() {
return A();
}

B MakeB() {
// The key bits are in here
#ifdef SLOW
A a(MakeA());
return B(a);
#else
return B(MakeA());
#endif
}

int main() {
std::cout << "Hello World!\n";
B obj = MakeB();
std::cout << &obj << "\n";
return 0;
}

如果我用 #define SLOW 注释掉并用 -s 优化运行它,我得到

Hello World!
A move
A d'tor
0x7fff5fbff9f0
A d'tor

这是预期的。

如果我在启用#define SLOW 并使用-s 优化的情况下运行它,我得到:

Hello World!
A copy
A move
A d'tor
A d'tor
0x7fff5fbff9e8
A d'tor

这显然不是很好。所以问题是:

为什么我没有看到在“SLOW”情况下应用 NRVO 优化?我知道编译器不需要应用 NRVO,但这似乎是一个常见的简单情况。

总的来说,我鼓励使用“SLOW”风格的代码,因为我发现它更容易调试。

最佳答案

简单的答案是:因为在这种情况下不允许应用复制省略。编译器只允许在极少数和特定情况下应用复制省略。该标准的引用是 12.8 [class.copy] 第 31 段:

... This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

  • in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value
  • [...]

显然 B(a) 的类型不是 A,即不允许复制省略。同一段落中的其他项目符号指的是诸如 throw 表达式、从临时文件中删除拷贝以及异常声明之类的内容。这些都不适用。

关于c++ - 为什么 clang 不使用 NRVO 对此进行优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20649951/

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