讨论《C++ Object Model 》一书中的NRV问题!。P66页 實施NRV最佳化 的问题。
因为抽空重新翻了一下,发现问题:
在67頁,最下面兩行:
> 這個程式的第一個版本不能實施NRV最佳化,因為test class
> 缺少一個copy constructor。
> 但是在66頁「在編譯器層面做最佳化」那一段中所列的碼顯示,
> 當編譯器把xx以__result取代,變成__result.X::X();
> 即default constructor被喚起。喚起default constructor
> 是可以理解的,可是編譯器轉換後的碼並沒有使用到
> copy constructor呀,為什麼67頁最後兩行卻說缺少一個
> copy constructor,就不能實施這個最佳化了呢?
观点讨论[解释+ 猜想]:
我的解釋是:
> 如同63頁與64頁「回返值的初始化」這一段,編譯器可能將
> 63頁下面的 X bar()函式定義轉換成64頁的虛擬碼,其中有
> 一行__result.X::X(xx); 這會使用到copy constructor。
>
> 轉換成64頁的碼後,65頁與66頁分述了兩種後續可能出現的
> 最佳化動作,其中一種即是66頁的編譯器層面做最佳化。
> 如此,雖然66頁最佳化後的碼看起來並不使用到copy constructor,
> 但是這些碼是根據像64頁那種樣子的碼(註一)最佳化而來的,
> 而若沒有copy constructor,根本無法轉換成64頁那種虛擬碼,
> 因為其中有一個呼叫copy constructor的動作。所以,雖然
> 66頁經過編譯器最佳化的結果省去了__result.X::X(xx);
> 這個copy constructor的呼喚動作(因為根本沒有xx了),
> 但若沒有明白提供一個copy constructor,卻無法讓編譯器
> 進行這樣的最佳化。
>
> 另一方面,我參考第5章,205頁最下面一段話:
> 「一般而言如果你的設計之中,有許多函式都需要以傳值(by value)
> 傳回一個local class object....那麼提供一個copy constructor
> 就比較合理--甚至即使default memberwise語意已經足夠。
> 它的出現會觸發NRV最佳化。然而,就像我在前一個例子中
> 所展現的那樣,NRV最佳化後將不再需要喚起copy constructor,
> 因為運算結果已經被直接計算於「將被傳回的object」體內了。」
> 所以,我提出如上所述那個解釋,但不確定是否正確,所
> 以e-mail給您以確認一下。
>
> 註一:當然,編譯器到底怎麼實作這些轉換動作,理論上
> 我們是未知的,不能一概而論。所以我寫「像64頁那種樣子的碼」。
2。Lippman 在 p67 最後一行所言『这个程式的第一个版本
不能实施 NRV 最佳化,因为 test class 缺少一个 copy constructor』,此语错误。
黄先生认为如果程式没有 explicit copy constructor,编译器会
自动为我们做出来(如为 trivial,则直接 bitwise copy;如为 nontrivial,
则由编译器为我们合成出一个 copy constructor)。因此,有没有 explicit
copy constructor 并不影响 NRV 最佳化的实施。他认为 NRV 最佳化主要是
由编译器 option 来决定要不要实施。他并且做了一些实验,判断 VC 和 gcc
都没有做到 NRV 最佳化,而其不做的理由不是因为技术上的困难,是为了
避免造成「user defined copy constructor 之副作用失效」-- 所谓副作用
是指,例如「在 user defined copy constructor 中做一个 cout 输出」之类
这种「与 memberwise copy 无关」的动作。
希望大家踊跃讨论!·!!