2011-10-25 135 views
0

我曾在一個示例應用程序下面的代碼:重載運算符<<返回的ostream&

ostream& operator<< (ostream& os, const ReferenceTest& rt) 
{ 
    os << rt.counter; //In this scenario, rt has a public int called counter 
} 

我很驚訝地得知,這個代碼不使用GCC 4.6.1編譯問題。由於我預期的原因,使用Visual Studio 2010時失敗,即我沒有返回對ostream的引用。但是,爲兩個平臺編譯的程序輸出是相同的(我有一個微不足道的main()寫測試輸出)。

符合哪些標準?我在這裏錯過了很明顯的東西嗎

-Derek

+0

感謝您的回覆。不會從任何(無效)函數返回某些東西的資格作爲編譯時錯誤?我會認爲這不僅僅是一個警告。同意 - 但是。 –

+0

另外,運行時行爲是巧妙編譯(如David建議的)還是巧合(K-ballo)的結果?如果它實際上試圖「修復」我的代碼,它似乎是越界越界...... –

+0

當檢測到問題時,一個好的編譯器會很努力地修復你的代碼。然而這是未定義的行爲。一個糟糕的編譯器可能什麼也不做,什麼都不說一個討厭的編譯器可能會向'degauss_hard_drive()'插入一個調用,並且什麼也不說。未定義的行爲意味着編譯器可以對你很好,並拒絕你的代碼,對你很好,並「修復」你的代碼,對你有意義並彈出包含代碼的驅動器。當涉及到編譯器對未定義行爲的響應時,任何事情都可以。 –

回答

2

編譯時是否啓用了警告?我用g ++得到warning: control reaches end of non-void function

您當然不希望編譯器停止在代碼中的第一個錯誤。你想讓它在一個膨脹的足球中儘可能多地捕捉。要做到這一點,編譯器必須修補你的錯誤代碼,以便它可以按下。在這種情況下,補丁很明顯:返回作爲參數提供的流。

不要相信編譯器免費提供的那些「修復」。他們什麼都不是免費的。修改你的代碼。

並始終編譯並啓用警告。

1

比缺少return語句以外的東西?缺乏它是未定義的行爲(我甚至認爲它是這種簡單情況下的編譯時錯誤)。可能發生的情況是,os << rt.counter表達式返回的值恰好被放置在預期整個operator<<的返回值相同的位置,這使得它只是偶然的工作。

+0

你是完全正確的,這是未定義的行爲。無論出於何種原因,GNU套件認爲達到非無效函數的結束值得僅僅是警告而不是彙編錯誤。它構成了一些返回值,並通過編譯進行壓縮。 –

+0

@David Hammen:檢查函數是否可能達到函數的終點是一個相當複雜的分析。我確定標準說「不需要診斷」。 –

+0

沒有理由說「不需要診斷」。 6.6。3第2段:「從函數末尾流出相當於沒有值的返回;這會導致返回值函數中出現未定義的行爲。」未定義的行爲不需要診斷。這並不意味着當編譯器檢測到UB時它必須保持沉默,或者編譯器必須發出已編譯的代碼。作爲一個編譯器錯誤處理結束的流程也是完全正確的。 –