作者littleshan (我要加入剑道社!)
看板C_and_CPP
标题Re: RVO vs inline
时间Wed Oct 21 13:01:28 2009
※ 引述《holymars ()》之铭言:
: RVO和NRVO是不一样的
: RVO也是不能影响语意的
: 根据inside the C++ object model的说法
[deleted]
: 以上是RVO
在这边我的看法和你有一些差异
首先 Stan 并没有说这叫作 RVO (他是说 user level optimizaion)
由 More Effective C++ item.20 来看
Jonathan 做的事情应该是「协助完成 RVO」
而不是 RVO 本身
那 RVO 是什麽?在我的看法就是规格书 12.8.15 第二条的一个子集合
如下:
class Foo {...};
Foo bar()
{
return Foo();
}
Foo x = bar();
这边 Foo() 会产生一个暂时物件
但 12.8.15 允许 compiler 不产生这个暂时物件
而直接用 default constructor 来初始化 x
又如这个例子
class Foo {
public:
Foo(int i);
};
Foo x = 10;
10 是 int 而不是 Foo,因此 compiler 使用 Foo::Foo(int) 产生一个暂时物件
再用这个暂时物件呼叫 copy-constructor
但 12.8.15 允许 compiler 省略後面的 copy-constructor
因此就变成直接用 Foo::Foo(int) 来初始化 x
以上是我的理解
因为我们对 RVO 的理解不同
以下我会改用 copy elision 来称呼这样的行为
[deleted]
: 上面是解释RVO和NRV的不同
: 然後来看看原本的问题
: : List Test::GetList()
: : {
: : return m_oList;
: : }
: : List oList = oTest.GetList();
: 嗯..其实这个函式既没有动用到RVO,也没有动用到NRV
OK
我要说的是
因为这个地方使用了 copy elision
所以省略了一次 copy construction
前面说省掉 copy assignment 是我说错
至於 GetList 是否 inline
并不会影响到 compiler 是否有启用 copy elision
因为 inline 不应该让程式执行结果产生不同
但 copy elision 是会有副作用的
也就是说
在一个不使用 copy elision 的 compiler 上面
即使 GetList 是 inline function
上述的程式码也应该要产生两次 copy construction
: 我用VC8.1 compile了一个完全不optimize的asm
: 就算是完全没有optimize的版本
: 也只在function里面做了一次copy ctor (compiler预设产生的那个)
这是对的
因为 copy elision 启用与否 会影响程式的最终行为
因此它不应该被视为 compiler optimizaion 的选项
而应该被视为 language feature
而 compile 时是否有 optimize 则不影响 compiler 是否使用 copy elision
和上面 function 是否有 inline 不应该影响 copy elision 的道理相同
另外
规格 12.8.15 只有写
When certain criteria are met, an implementation
is allowed to omit
the copy construction of a class object, ...
照这样看起来 copy elision 就像是个 implementation-defined behavior
不过目前大多数的 compiler 都把 copy elision 默认为规格的一部份就是了
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.29.108