我想确保我的例程尽可能利用(N)RVO。除了通过最终的反汇编进行解析之外,我是否可以执行其他操作或检查是否正在使用(N)RVO编译例程?在这一点上,我对MSVC和GCC最为感兴趣。

最佳答案

不,不是。

但是,编写代码时可以遵循准则。

未命名返回值优化

每当您返回一个临时文件时,即使在 Debug模式下,这几乎都是触发的。

return MyObject(....);

命名返回值优化

每当函数总是返回相同的临时对象时,都会触发该事件:
MyObject func() {
  MyObject result;
  if (...) { return result; }

  result.push(0);
  return result;
}

您可以混合使用它们,但是在这种情况下,编译器几乎不可能应用RVO:
MyObject func() {
  MyObject result;
  if (...) { return MyObject(...); }

  return result;
}

在这里,很可能一种返回将从RVO中受益,而另一种则不会。我敢打赌首先要进行优化,因为如果您在返回槽中推测性地创建result并突然需要采取if分支,那么您将被困住。请注意,只需对语句重新排序即可:
MyObject func() {
  if (...) { return MyObject(...); }

  MyObject result;

  return result;
}

因此,NRVO的经验法则是,在return声明和result声明之间应没有return result;语句,该语句返回除result本身以外的任何内容。

如果您遵循此规则,那么您将有机会赢得您的青睐。然后,这只是代码审查的问题。

而且,由于您在知道自己确实需要变量之前就没有声明变量,因此也使代码更易于阅读!

关于c++ - 我如何确定例行程序正在利用(N)RVO?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9621720/

10-11 17:56