复制省略和返回值优化相对于复制构造函数
Copy elision and return value optimization versus copy constructor
我一直在读关于复制省略和返回值优化如何通过避免调用对象复制构造函数来提高速度的文章。我理解这些机制是如何工作的,但我想知道这是否会导致程序的行为与人们预期的不一样。
本质上,我的问题是;如果我们编写复制构造函数而不创建作为另一个对象副本的对象,会发生什么?换句话说,如果
AClass original;
AClass copy ( original );
// copy == original -> false
例如,我们有一个这样的类:
// AClass.hpp
struct AClass
{
static int copyCount;
int copyNumber;
AClass():copyNumber(0){}
AClass( AClass const& original ):copyNumber(++copyCount){} // I think this is the signature for the copy constructor
};
// AClass.cpp
int AClass::count ( 0 );
这显然是一种可怕的行为,我并不是说我会做这样的事。然而,这一点是站得住脚的;如果我们依赖复制的副作用呢?在本例中,跟踪我们制作了多少份副本。我希望优化不会影响程序的运行方式。但是,复制省略可能会导致以下代码失败:
// Main.cpp
AClass MakeAClass()
{
return AClass();
}
int main()
{
AClass copy ( MakeAClass() );
if ( AClass::copyCount == 1 )
{
return 0;
}
else
{
return -1;
}
}
当我在没有优化的调试模式下构建时,这可能会返回0,但当我打开优化并且MakeAClass的返回直接放在副本上,跳过副本构造函数时,它会突然失败。
当编译器尝试这些优化以寻找副作用时,是否进行了检查?当您要求复制时,期望代码执行复制是错误的吗?
是。如果复制构造函数(或移动构造函数或析构函数)有副作用,则复制省略可以更改代码的行为。
这就是重点。如果它不能改变行为,就没有理由在标准中提及它。不改变行为的优化已经包含在假设规则中。(1.9/1)即:
本国际标准中的语义描述定义了参数化的不确定性抽象机。这个国际标准对一致性的结构没有要求实现。特别是,他们不需要复制或模仿抽象机器的结构。相反,符合的实现被要求(仅)模仿抽象的可观察行为机器如下所述。
复制省略在标准中被明确提及,正是因为它可能违反此规则。
相关文章:
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- MOVNTI 存储是否相对于由同一线程创建的其他 MOVNTI 存储重新排序?
- 我如何知道字符串中字符相对于英文字母的位置值?
- 非静态成员引用必须相对于特定对象
- 如何在相对于观看方向的地形中移动
- CRTP相对于抽象类的优势
- 互斥锁能否保护相对于特定指针的数据?
- 在Visual Studio Code(.json配置)中设置相对于工作区路径的c / c ++项目的包含路径
- 是 C++ gcc HEAD 10.0.0 20190 相对于好友函数的错误吗?
- 相对于继承的构造函数,gcc 编译器是否还有一个错误?
- DirectX矩阵:相对于面向方向的转换(例如在FPS中)
- stat() 相对于文件系统是原子的
- 如何在3D世界中获得对象相对于父母的绝对位置
- 类相对于数据结构的重要性
- 在 C/C++ 中乘以低数字(相对于高数字)是否更快?
- 在 C++ 中,映射相对于堆的优势是什么?
- CMake:C++包含相对于基目录的内容
- 相对于另一个向量对一个向量进行排序 - 最有效的方法
- 移动构造函数相对于复制构造函数的优势是什么?复制构造函数使用bool来表示是复制还是移动
- 复制省略和返回值优化相对于复制构造函数