C++ Object Model 答客問 (3) - NRV 最佳化
C++ Object Model 答客問 (3) - NRV 最佳化
侯捷 jjhou@ccca.nctu.edu.tw
2000.03.25 第一次發表於
清大.楓橋驛站(140.114.87.5).電腦書訊版(Computer/CompBook)
本文將於日後整理於 侯捷網站
侯捷網站:www.jjhou.com
----------------------------------------------------------------
leetron wrote (2000/02/11) :
> 您好,關於深度探索C++物件模型一書,2.3節程式
> 轉化語意學的部分,有個問題
> 想請教您。
>
> 問題:
> 在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頁那種樣子的碼」。
侯捷回覆:
我最害怕的事情就是,讀者寫信來討論《深度探索 C++ 物件模型》
一書內容。因為都是些高手提出些深奧的題目,而我必須把塵封的
記憶找出來… :)
OK,作者(或譯者)沒有抱怨的權利 :)。我的回覆如下。
首先,我要說 leetron 把他的意思描述得非常清楚。在我收到
的讀者來函中,算是上品 — 尤其是描述這麼複雜的思路。
其次,我同意 leetron 說:
> 轉換成64頁的碼後,65頁與66頁分述了兩種後續可能出現的
> 最佳化動作,其中一種即是66頁的編譯器層面做最佳化。
但是我不同意 leetron 這樣的看法:
> 如此,雖然66頁最佳化後的碼看起來並不使用到copy constructor,
> 但是這些碼是根據像64頁那種樣子的碼(註一)最佳化而來的,
我認為,NRV 最佳化並非是由 p63 的原始碼而至 p64 的虛擬碼,
再至 p66 的最佳化。我認為是從 p63 的原始碼直接至 p66 的最佳化。
所以,似乎可以不需要 copy ctor。
但這麼一來我也無法解釋為什麼 lippman 在 p67 最下強調
「必須要有 copy ctor 才能實施 NRV 最佳化」。
以下是其他讀者的討論,給您參考。
-- quote -- (引自 www.jjhou.com :書籍勘誤/深度探索 C++ 物件模型)
★黃俊達先生認為: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 無關」的動作。
★侯俊傑答覆:頗有道理。但請注意,Lippman
在 p.205 下方, p.221 上方等處,仍再三強調 copy constructor
對於 NRV 最佳化的導引之功,不知是否其間有什麼是我們沒想到的?
★唐志青先生亦來信對於 NRV 提出與黃俊達先生相同的看法。感謝。
-- unquote --
-- the end
--
※ Origin: 楓橋驛站<bbs.cs.nthu.edu.tw> ◆ Mail: jjhou@ccca.nctu.edu.tw
CompBook 近期熱門文章
PTT數位生活區 即時熱門文章