我怎样才能确定一个例程正在利用(N)RVO?

fbr*_*eto 5 c++ optimization gcc visual-c++ return-value-optimization

我想确保我的例程尽可能利用(N)RVO.除了解析生成的反汇编之外,还有什么我可以做或检查是否正在使用(N)RVO编译例程?在这一点上,我最感兴趣的是MSVC和GCC.

Mat*_* M. 7

不,不是真的.

但是,您可以在编写代码时遵循指南.


未命名的返回值优化

即使在调试模式下,每次返回临时值时都会触发此操作.

return MyObject(....);
Run Code Online (Sandbox Code Playgroud)

命名返回值优化

每次函数总是返回相同的临时对象时,这几乎都会被触发:

MyObject func() {
  MyObject result;
  if (...) { return result; }

  result.push(0);
  return result;
}
Run Code Online (Sandbox Code Playgroud)

您可以混合使用这些,但在这种情况下编译器几乎不可能应用RVO:

MyObject func() {
  MyObject result;
  if (...) { return MyObject(...); }

  return result;
}
Run Code Online (Sandbox Code Playgroud)

在这里,一个回报可能会受益于RVO而另一个则不受益.我敢打赌第一个被优化,因为如果你推测性地result在返回槽中创建并突然需要采取if分支,你就会陷入困境.请注意,只需重新排序语句就可以了:

MyObject func() {
  if (...) { return MyObject(...); }

  MyObject result;

  return result;
}
Run Code Online (Sandbox Code Playgroud)

因此,NRVO的经验法则是return声明result和声明之间不应该return result;声明返回除result自身以外的任何内容.


如果你遵循这个,你可以为你赢得赔率.然后,这只是代码审查的问题.

并且您还可以使代码更易于阅读,因为在知道您确实需要它们之前不会声明变量!