2014-01-12 69 views
1

-O0或任何其他-O [其他級別]中包含的-fno-elide-constructors是否?-O0或任何其他優化級別中包含-fno-elide-constructors?

在我看來,-fno-elide-constructors是一個優化標誌,而-O是優化級別。因此,一些-O級別可能包括flag -fno-elide構造函數。 我對不對?

換句話說,-fno-elide-constructors和-O ..之間是否有任何關係?

+0

我相信它可以通過優化設置添加,但我不確定哪一個。 – 0x499602D2

回答

2

換句話說,-fno-elide-constructors 和-O ..之間是否有關係?

是的,有一種關係,雖然很簡單:gcc最有可能會在-O0級別修改構造函數,除非您明確禁用它。請參閱底部的示例代碼以獲取證明。

儘管如此,編譯器可以做很多令人討厭的事情,請參閱RVO force compilation error on failure。底線是:您總是需要檢查生成的程序集以查看引擎蓋下真正發生的情況。

請記住(from Working Draft, Standard for Programming Language C++, N3797這是C++ 14的最接近我能找到):

12.8/31當滿足一定的條件,實現允許忽略複製/移動類對象的構造,即使爲複製/移動操作選擇的構造函數和/或對象的析構函數具有副作用。 [...]


代碼充實我的發言:

#include <cstdio> 
constexpr int size = 1024; 

struct A { int array[size] = { 0 }; }; 

int main() { 
    A a = A(); 
    std::printf("%d\n", a.array[size-1]); 
} 

隨着g++ -std=c++11 -Wall -O0 -S elide.cpp,在生成的彙編代碼中只有一個

call A::A() 

但是,與g++ -std=c++11 -Wall -O0 -fno-elide-constructors -S elide.cpp我得到:

call A::A() 
    [...] 
    call A::A(A&&) 

即使禁用優化與-O0,你還是要還禁用省音,如果你需要它由於某種原因被禁用。

+0

關於:'因爲有些編譯器在每個允許的情況下都不執行復制,所以依賴副本/移動構造函數和析構函數的副作用的程序是不可移植的。「這並不確切。該行爲在標準(C++ 14 12.8/31和/ 32,甚至C++ 98 12.8/15)中有明確的描述,因此它是「便攜」的。只是一些編譯器會比其他編譯器做更多的拷貝。有點像「長」,在某些平臺上可以是32位,而在其他平臺上可以是64位。我的猜測是,如果你需要禁用RVO以確保你會有一些行爲,你正在做一些可怕的事情。 – paercebal

+0

@paercebal謝謝,修正!我想無論誰寫了「便攜式」意味着如果你切換到另一個編譯器然後奇怪的事情可能會發生...... :(是的,我完全同意,如果有人依賴於這種行爲,這是可腥的無論如何,更新我的答案,謝謝! – Ali

相關問題