2012-03-31 27 views
2

假設我有這樣的假設,奇數和不直觀的情況複製省略導致不同的結果

#include <iostream> 

    struct A 
    { 
     A() 
     { 
     member = 1; 
     } 

     A(const A &) 
     { 
     member = 2; 
     } 

     int member; 
    }; 

    int main() 
    { 
     A a = A(); 
     A b = a; 
     std::cout << a.member << std::endl; 
     std::cout << b.member << std::endl; 
     return 0; 
    } 

我知道,複製省略意味着a將只是默認構造函數初始化和B就與副本進行初始化構造函數。我也知道(至少在gcc上),你可以告訴編譯器不要做任何複製elision。

我的問題是有一些方法讓編譯器不使用複製elision 只爲這個類

我意識到在任何實際情況下的答案都是99.9%的時間找到其他方式,而我沒有其中一個0.01%的情況(這是一個實際的假設問題,而不是「假設的問題「)

回答

5

複製省略由標準允許的,它是不需要遵循AS-如果規則[#1],所以,你不應該依賴行爲的單一優化。

你可能在GCC的情況下,使用一些編譯器的設置,如,從man page

-fno-elide-constructor

C++標準允許實現省略創建一個臨時它僅用於初始化另一個相同類型的對象。指定此選項將禁用該優化,並且 會強制G ++在所有情況下調用複製構造函數。

但是,使用它可以讓您的代碼在不同編譯器之間無法移植。


[#1]C++ 03 1.9「程序執行:

符合實現需要(僅)模擬抽象機的可觀察行爲

腳註進一步詳細描述了它

這個規定有時被稱爲「假設」規則,因爲只要結果就好像要求被遵守一樣,實現可以自由地忽略本國際標準的任何要求,只要可以從可觀察的程序行爲。例如,一個實際的實現不需要評估表達式的一部分,如果它可以推斷出它的值沒有被使用,也不會產生影響程序可觀察行爲的副作用。

+0

您有** As-If **規則的鏈接或定義嗎?好奇的頭腦想知道! – 2012-03-31 16:43:51

+0

我知道你可以用這個選項關閉整個功能,我真的很想知道是否可以根據具體情況關閉它,但是我想沒有其他人真的不需要它,實現該功能只會允許編寫錯誤的代碼,並且實際上不會使任何優秀的代碼受益。 – SirGuy 2012-03-31 16:47:17

+0

@EmileCormier:檢查更新後的答案。希望那個坐立不安的好奇心:) – 2012-03-31 16:49:05

3

RVO/NRVO是標準明確允許的,通常是Good Thing™,幾乎沒有好的設計被破壞,所以沒有任何編譯器編寫者需要實現這些選項。

我不知道有任何編譯器允許您在個案基礎上關閉它。

相關問題