C++ Object Model 答客問 (3) - NRV 最佳化

看板CompBook (電腦用書)作者時間25年前 (2000/03/25 22:48), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
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
文章代碼(AID): #utD6v00 (CompBook)
文章代碼(AID): #utD6v00 (CompBook)