-O0或任何其他-O [其他級別]中包含的-fno-elide-constructors是否?-O0或任何其他優化級別中包含-fno-elide-constructors?
在我看來,-fno-elide-constructors是一個優化標誌,而-O是優化級別。因此,一些-O級別可能包括flag -fno-elide構造函數。 我對不對?
換句話說,-fno-elide-constructors和-O ..之間是否有任何關係?
-O0或任何其他-O [其他級別]中包含的-fno-elide-constructors是否?-O0或任何其他優化級別中包含-fno-elide-constructors?
在我看來,-fno-elide-constructors是一個優化標誌,而-O是優化級別。因此,一些-O級別可能包括flag -fno-elide構造函數。 我對不對?
換句話說,-fno-elide-constructors和-O ..之間是否有任何關係?
換句話說,-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
,你還是要還禁用省音,如果你需要它由於某種原因被禁用。
關於:'因爲有些編譯器在每個允許的情況下都不執行復制,所以依賴副本/移動構造函數和析構函數的副作用的程序是不可移植的。「這並不確切。該行爲在標準(C++ 14 12.8/31和/ 32,甚至C++ 98 12.8/15)中有明確的描述,因此它是「便攜」的。只是一些編譯器會比其他編譯器做更多的拷貝。有點像「長」,在某些平臺上可以是32位,而在其他平臺上可以是64位。我的猜測是,如果你需要禁用RVO以確保你會有一些行爲,你正在做一些可怕的事情。 – paercebal
@paercebal謝謝,修正!我想無論誰寫了「便攜式」意味着如果你切換到另一個編譯器然後奇怪的事情可能會發生...... :(是的,我完全同意,如果有人依賴於這種行爲,這是可腥的無論如何,更新我的答案,謝謝! – Ali
我相信它可以通過優化設置添加,但我不確定哪一個。 – 0x499602D2