我必须依赖编译器 NRVO 吗?
Do I have to rely on compiler NRVO?
我需要调用一个函数,它为我返回一个对象。问题在于该对象有一个析构函数,该析构函数可能会在函数输出分配给另一个对象之前破坏数据。在我的程序中,我有一个运算符+,它添加两个矩阵并返回两个矩阵的总和:
C=A+B
根据名称返回值优化 (NRVO(,以下代码不应立即调用析构函数:
Matrix operator+(const Matrix &m1, const Matrix &m2)
{
Matrix sum;
m1.clone(sum);
for...
for...
sum.members[i][j]+=m2.members[i][j];
return sum;
}
我的问题是我对信任 NRVO 没有信心,因为它取决于编译器。如果我把代码交给其他人,他可能会编译代码,他的编译器会给出不同的结果。
那么,有没有办法强制编译器给我我到底需要什么,或者我必须将我的代码更改为不需要的形式,如下所示?
Matrix sum(Matrix &result, const Matrix &m1, const Matrix &m2)
编辑:
为了解释更多,我假设通过考虑 NRVO,probram 运行如下:
compiler reaches to C=A+B
operator + is called
object sum is created
object sum is calculated as sum of m1 and m2
sum is returned but its destructor is not called
the value of sum is directed to variable C
after function containing variable C reaches end, the destructor of C is called.
虽然不应用 NRVO,但我期望:
compiler reaches to C=A+B
operator + is called
object sum is created
object sum is calculated as sum of m1 and m2
sum is returned and its destructor is called which releases all data allocations
the return value of the operator+ is already destroyed so an invalid data is associated to variable C
...
问题在于该对象有一个析构函数,该析构函数可能会在函数输出分配给另一个对象之前破坏数据。
这不是问题。对象将被正确复制,或者通过优化消除不必要的复制。如果你的复制 ctor 实现得当,最终结果将是相同的(当然,不太理想的代码除外(。如果对象复制非常昂贵,您可能应该在写入语义上使用 copy,而实际的 Matrix 对象将是堆上创建的真实对象的精简包装器。
不应用 NRVO 时实际会发生什么:
compiler reaches to C=A+B
operator + is called
object sum is created
object sum is calculated as sum of m1 and m2
temporary object of type Matrix created as a copy of object sum
object sum destroyed
temporary assigned to C
如您所见,最终结果是相同的,只是效果较差(创建了临时对象(
相关文章:
- C/C++编译器通常会删除重复的库吗
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- Win32编译器选项和内存分配
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++,我收到一个无法理解的编译器错误
- 在线编译器中的分段C++没有打印消息
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- C/C++预处理器是否可以检测一些编译器选项
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 我需要知道编译器如何在cpp中使用析构函数
- 编译器如何区分std::vector的构造函数
- CLANG 编译器 说:变量"PTR"可能未初始化
- 告诉c++编译器该参数没有别名
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么所有C++编译器都会崩溃或挂起此代码
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 我必须依赖编译器 NRVO 吗?
- C++11编译器何时会使RVO和NRVO优于移动语义和常量引用绑定