RVO/NRVO 不能在 Clang++ 的 C++17 中禁用吗?

RVO/NRVO can not be disabled in C++17 in Clang++?

本文关键字:C++17 NRVO 不能 Clang++ RVO      更新时间:2023-10-16

我从使用 Clang++ 在不同C++版本下运行的同一代码片段中得到了不同的结果。当我使用 C++17 编译代码时,编译器似乎自动调用了 RVO/NRVO,好奇这是一个错误还是不同的功能?

苹果 clang 版本 11.0.0 (clang-1100.0.33.17(

使用以下命令在C++11下运行:

clang++ test.cc -fno-elide-constructors -std=c++11 -o test

结果:

Move Constructor
Move Constructor
100

使用以下命令在C++17下运行:

clang++ test.cc -fno-elide-constructors -std=c++17 -o test

结果:

100

代码 (test.cc(:

struct A {
A() = default;
A(int v) : p(new int(v)) {}
~A() { delete p; }
A(const A&) = delete;
A& operator=(const A&) = delete;
A(A&& rhs) noexcept : p(rhs.p) { 
std::cout << "Move Constructor" << std::endl; 
rhs.p = nullptr; 
}
A& operator=(A&& rhs) noexcept {
std::cout << "Move Operator" << std::endl;
p = rhs.p; 
rhs.p = nullptr; 
return *this; 
}
int getPV() const { return *p; }
private:
int* p;
};
A getTempA(int v) { return A(v); }
int main(int argc, char** argv) {
auto a = getTempA(100);
std::cout << a.getPV() << std::endl;
return 0;
}

在 C++17 中,语言定义发生了变化。在你问题的代码中,没有临时的,也没有什么可以省略的。

prvalue 表达式可以被视为具有延迟实例化。表达式auto a = getTempA(100);根据定义与A a(100);相同。