2014-11-20 77 views
0

我的理解是,爲了編譯器能夠執行命名返回值優化(NRVO),必須在函數體中的任何其他值之前聲明返回值。我懷疑這可能是由於堆棧展開的順序,如果發生異常但我不確定。指定的返回值必須是第一個在函數體中聲明的原因是什麼?爲什麼返回值需要是NRVO首先聲明的本地值?

class C{}; 
C f(){ 
    C ret; //NRVO possible 
    return ret; 
} 
C g(){ 
    int i; 
    C ret; //NRVO not possible? 
    return ret; 
} 

使用案例:

auto c = f(); 
auto c2 = g(); 

編輯: 謝謝你幫助我瞭解這一切應答者,我開始懷疑,錢德勒卡魯斯的說法在這裏:http://www.youtube.com/watch?v=fHNmRkzxHWs分鐘32:30可能是誤導和/或我只是誤解了它。返回變量首先被聲明並不重要。

+3

可能有一些* *編譯強加此限制,但一般的理解是根本缺陷 - 變量定義爲了不啓用/禁用NRVO。 – 2014-11-20 16:54:36

+4

你測試了這個假設嗎?如果是這樣,用哪個編譯器? – juanchopanza 2014-11-20 17:11:53

+0

這[過時的鏈接](http://msdn.microsoft.com/en-us/library/ms364057(v = vs.80).aspx)可能會有所幫助 – anatolyg 2014-11-20 19:04:13

回答

0

該標準對複製刪除變量的聲明/定義的順序沒有要求。請注意,該標準表示「實現爲允許」,而不是它應該,應該等等。我們可以看到複製刪除發生在clang and gcc而不是MSVC,進一步強化了這是一個實現定義的優化。

§12.8/ 31描述了複製省略:

[..]複製/移動操作的此省音,稱爲複製省略,在下列情況下是允許的(其可以被組合以 消除多個副本):

- 在與類返回類型,函數返回語句時 表達式是一個非易失性自動對象的名稱(其他 不是函數或catch子句參數)用相同 CV-非限定類型作爲函數返回類型,複製/移動 操作可以通過直接 構造自動物體插入函數的返回值

省略 - [..]

相關問題