簡體   English   中英

對未命名對象的RVO(返回值優化)是否具有普遍保證的行為?

[英]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的對象,編譯器可以忽略無,一個或兩個副本生成所有三個可能的輸出。

小心翼翼地說它的實現定義。 現代編譯器足夠智能,可以進行這種優化。

但是不能保證這些行為在實現中完全相同。 這就是實現定義的行為的全部內容。

在這種情況下,“允許”意味着012是標准符合要求的輸出。

它無法保證。 如果你試圖連貫地寫出這樣的保證,你會發現不可能這樣做。

例如,請考慮以下代碼:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM