[英]Why does this compile on Ideone?
好的,所以我在Ideone上亂搞並意外地提交了這段代碼,但令我驚訝的是它實際編譯並運行輸出值為0, 這里 。
#include <iostream>
using namespace std;
const int five( )
{
const int i = 5;
}
int main() {
cout << five( ) << endl;
return 0;
}
然后我在Visual Studio中嘗試了這個,然而在Codepad上,兩個都無法編譯,因為five()
沒有返回值,正如人們所期望的那樣。 我的問題當然是,為什么這個在Ideone上編譯正常,即使代碼,我的理解是錯誤的,不應該編譯。
簡單而簡單(來自C ++ 11 6.6.3“返回語句”):
流出函數末尾相當於沒有值的返回; 這會導致值返回函數中的未定義行為。
所以編譯器幾乎可以做任何想做的事情。 顯然,診斷是我更喜歡編譯器的東西,但有時很難診斷(比如返回是在條件邏輯中,並且永遠不會達到函數的'結束')。
請注意,我使用GCC 4.6.1(使用Wall
選項)收到以下警告:
test.cpp:8:1: warning: no return statement in function returning non-void [-Wreturn-type]
我不知道什么ideone傳遞給GCC的選項(我想象-Wall
會做與ideone使用4.3.4版本相同)。
一些相關信息:
在C中,聲明返回值的函數在某些情況下實際上不會這樣做是可以的。 在C中,如果實際使用了函數的返回值,它只會導致未定義的行為。 預標准C並不總是支持void
類型,因此未返回任何內容的函數通常被聲明為顯式或隱式返回int
。 從C99 6.9.1 / 12“函數定義”:如果到達終止函數的}
,並且調用者使用函數調用的值,則行為未定義。
另外,正如一些注釋中所提到的,流出main()
的末尾是由C ++和C99以及后來專門處理的。
不從非void函數返回值是錯誤的,但並非所有編譯器都將其視為錯誤 - 例如,GCC在遇到此錯誤時僅發出警告。 其他編譯器可能是偏執的(並且它們是正確的)並且不允許您編譯這樣的代碼。 當然,可以使用不同的開關和選項修改編譯器行為。
返回值0只是一個隨機值 - 它可能同樣是255,-1或任何其他垃圾,因為這樣做是未定義的行為(除了main,C99指定應該假定隱式0返回值) 。
似乎ideone不顯示警告,它只在出現錯誤時顯示編譯器輸出。 在ideone正在使用的GCC版本(gcc 4.3)上,這不是錯誤,它只是一個警告。
代碼具有未定義的行為。 即使您正在做的事情是錯誤的,編譯器也不需要診斷它。 另一點是,ideone使用的是現在相當古老的gcc版本。 一個合理的當前版本的gcc(例如,4.7)將至少給你一個警告,聲明你的函數被聲明為返回一個值,但不是 - 但默認情況下不是。 你必須用類似-Wall
東西來打開警告(但作為一般規則,我總是至少使用-Wall和gcc)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.