对于std::atomic
,复制构造函数被删除,由于复制省略,这应该只能在c++ 17或更高版本中编译:
std::atomic<int> t_int = 1;
我期望它不使用-fno-elide-constructors
标志编译,但它仍然编译:
https://godbolt.org/z/nMvG5vTrK
为什么会这样?
c++ 17并没有简单地说以前可选的返回值优化现在是强制性的。语言的实际描述发生了变化,因此从一开始就不再创建临时对象了。
因此,从c++ 17开始,不再有可以省略的构造函数调用。因此,-fno-elide-constructors
没有添加任何临时创建是有道理的。那是违反语言规则的。
在c++ 17之前,语言描述了创建一个临时对象,从该对象初始化变量,然后添加了编译器允许省略该临时对象。因此,无论是否使用-fno-elide-constructors
,编译器省略或不省略临时副本都是符合标准的。
我希望它不会使用-fno-elide-constructors标志编译,
给定标志对返回值优化(也称为RVO)从c++ 17起没有影响。这是因为它不再被认为是一个优化(从c++ 17开始),而是一个语言保证.
From mandatory copy elison:
在下列情况下,编译器被要求省略类对象的复制和移动构造,即使复制/移动构造函数和析构函数具有可观察到的副作用。对象直接构造到存储中,否则它们将被复制/移动到中。。复制/移动构造函数不需要存在或可访问:
- 在对象的初始化中,当初始化表达式为prvalue与变量类型相同的类类型(忽略cv-qualification):
(强调我的)
这意味着t_int
是直接从prvalue
1
构造的。与NRVO不同,-fno-elide-constructors
对RVO没有影响。因此,删除复制构造函数对您的情况没有影响。
也许一个例子可以帮助说明相同的,
struct Custom
{
public:
Custom(int p): m_p(p)
{
std::cout<<"converting ctor called"<<std::endl;
}
Custom(const Custom&) = delete; //deleted copy ctor
private:
int m_p = 0;
};
int main()
{
Custom c = 1; //works in C++17 but not in Pre-C++17
}