2017-08-08 55 views
14

看看這段代碼:返回*&object時是否允許複製/移動elision?

#include <stdio.h> 

struct Foo { 
    Foo() { } 
    Foo(const Foo &) { printf("copy\n"); } 
    Foo(Foo &&) { printf("move\n"); } 
}; 

Foo getFoo() { 
    Foo f; 
    return *&f; 
} 

int main() { 
    getFoo(); 
} 

C++ 14標準說(12.8/31),即允許複製/移動省音:在一個函數

return語句中有一類返回類型,當 表達式是具有相同cv-未定義 類型的非易失性自動對象(函數或catch-clause參數除外)的名稱作爲函數返回類型時,可以省略複製/移動操作 通過將自動對象直接構建到中函數的返回值

在我的示例中,返回表達式不是名稱,所以我不認爲允許使用elision。

我檢查GCC /鐺/ MSVC,雖然鐺/ MSVC不復制的Elid,GCC一樣。 GCC在這裏違反標準嗎?

+0

好吧,我不明白爲什麼編譯器將保持冗餘'* '和'&'操作符。另外,您使用的是哪個版本的編譯器?你是用C++ 14模式構建的嗎?另外,在引用標準時,請指明代碼來自哪裏(名稱或章節/章節編號)。 –

+0

在完全不相關的說明中,爲什麼使用'printf'輸出?爲什麼不'std :: cout'? –

+2

@Someprogrammerdude - 編譯器可能不會將它們保留在發出的代碼中。但是它們確實影響了標準觀點表達式的語義。這根本不是一個id表達式(或名稱)。 – StoryTeller

回答

0

首先,「爲假設」規則在這裏並不適用,因爲你的複製和移動構造函數有副作用(他們執行IO)。因此,GCC不能在該標題下刪除複製/移動。

快速瀏覽,我看不到任何其他的措辭將允許省音,所以我認爲這是在GCC的錯誤。另一方面,我非常喜歡這個標準,以擴大複製/移動範圍,以包含這個案例。 (在你提出的小例子,我看不出它是如何產生的問題 - 我相信你有一個大的例子,其中它。)

+0

即使在這種情況下有副作用,編譯器也可以繼續複製/移動。 – Zereges

+0

@Zereges當複製/移動elision被允許時,即使編譯器有*副作用*(在標準中定義的形式意義上)也是允許的。我的第一段的要點是,如果施工人員沒有副作用,那麼即使在12.8/31(根據「如果」規則)下不允許使用「省略」,他們也可以被省略。 12.8/31不適用「在這種情況下」,「如果」不適用「在這種情況下」=> elision是一個錯誤。 –

+0

@Zereges我是否需要擴展我的答案以包含上述評論? –