[英]Is RVO (Return Value Optimization) on unnamed objects a universally guaranteed behavior?
這個問題在不同方面(也僅限於gcc)。 我的問題僅適用於未命名的對象 。 允許 返回值優化 更改生成的程序的可觀察行為 。 這似乎也在標准中提到。
然而,這個“允許”一詞令人困惑。 這是否意味着RVO 可以保證在每個編譯器上發生。 由於RVO下面的代碼改變了它的可觀察行為:
#include<iostream>
int global = 0;
struct A {
A(int *p) {}
A(const A &obj) { ++ global; }
};
A foo () { return A(0); } // <--- RVO happens
int main () {
A obj = foo();
std::cout<<"global = "<<global<<"\n"; // prints 0 instead of 2
}
該程序是否假設所有實現都打印global = 0
,而不管foo
的編譯器優化和方法大小如何?
根據標准,程序可以打印0,1或2.C ++ 11中的特定段落是12.8p31,以:
當滿足某些條件時,允許實現省略類對象的復制/移動構造,即使該對象的復制/移動構造函數和/或析構函數具有副作用。
請注意,兩個復制元素都不是屬於as-if規則的優化(這要求程序的行為與同一程序的行為一致- 如果沒有進行優化)。 標准明確允許實現生成不同的可觀察行為,程序員可以讓您的程序不依賴於此(或接受所有三種可能的結果)。
注2:1在任何答案中均未提及,但這可能是結果。 有兩個可能的副本發生,從函數中的局部變量到返回的對象到main
的對象,編譯器可以忽略無,一個或兩個副本生成所有三個可能的輸出。
小心翼翼地說它的實現定義。 現代編譯器足夠智能,可以進行這種優化。
但是不能保證這些行為在實現中完全相同。 這就是實現定義的行為的全部內容。
在這種情況下,“允許”意味着0
或1
或2
是標准符合要求的輸出。
它無法保證。 如果你試圖連貫地寫出這樣的保證,你會發現不可能這樣做。
例如,請考慮以下代碼:
std::string f() {
std::string first("first");
std::string second("second");
return FunctionThatIsAlwaysFalse() ? first : second;
}
函數FunctionThatIsAlwaysFalse
總是返回false
,但是只能進行模塊間優化。 標准是否要求每個編譯器進行模塊間優化,以便在這種情況下可以使用RVO? 那會怎么樣? 或者,當需要進行模塊間優化時,是否應該禁止任何編譯器使用RVO? 那會怎么樣? 怎么能阻止那些足夠智能的編譯器看到RVO可以做到這一點而那些不是沒有做到的?
標准列表是否需要每個優化編譯器都支持RVO? 在其他情況下是否應該禁止RVO? 那種優化編譯器的問題難道不會失敗嗎?
那么編譯器認為RVO會降低性能的情況又如何呢? 是否應該要求編譯器進行優化,它認為是壞的? 例如:
if(FunctionCompilerKnowsHasNoSideEffectsAndThinksMostlyReturnsFalse())
return F(3); // Here RVO is a pessimization
else
{
Foo j=F(3);
return Foo(j);
}
這里,如果編譯器不需要執行RTO,如果可以避免if
和函數調用,因為沒有RTO,代碼在兩半中都是相同的。 你是否應該強制編譯器進行優化,它認為會讓事情變得更糟? 為什么?
真的沒辦法做出這樣的保證工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.