假設你用C++編寫了一個函數,但卻心不在焉地忘記輸入字return
。在這種情況下會發生什麼?我希望編譯器會抱怨,或者一旦程序到達這一點,至少會出現分段錯誤。但是,實際發生的情況更糟糕:該程序發出垃圾。不僅如此,實際產量取決於優化的水平!下面是一些代碼,說明此問題:在C++中缺少返回值和優化的不規則行爲
#include <iostream>
#include <vector>
using namespace std;
double max_1(double n1,
double n2)
{
if(n1>n2)
n1;
else
n2;
}
int max_2(const int n1,
const int n2)
{
if(n1>n2)
n1;
else
n2;
}
size_t max_length(const vector<int>& v1,
const vector<int>& v2)
{
if(v1.size()>v2.size())
v1.size();
else
v2.size();
}
int main(void)
{
cout << max_1(3,4) << endl;
cout << max_1(4,3) << endl;
cout << max_2(3,4) << endl;
cout << max_2(4,3) << endl;
cout << max_length(vector<int>(3,1),vector<int>(4,1)) << endl;
cout << max_length(vector<int>(4,1),vector<int>(3,1)) << endl;
return 0;
}
這裏就是我得到的,當我在不同的優化級別編譯:
$ rm ./a.out; g++ -O0 ./test.cpp && ./a.out
nan
nan
134525024
134525024
4
4
$ rm ./a.out; g++ -O1 ./test.cpp && ./a.out
0
0
0
0
0
0
$ rm ./a.out; g++ -O2 ./test.cpp && ./a.out
0
0
0
0
0
0
$ rm ./a.out; g++ -O3 ./test.cpp && ./a.out
0
0
0
0
0
0
現在想象一下你正在試圖調試功能MAX_LENGTH。在生產模式下,你會得到錯誤的答案,所以你在調試模式下重新編譯,現在當你運行它時,一切正常。
我知道有很多方法可以完全避免這種情況下,加入適當的警告標誌(-Wreturn-type
),但我仍然有兩個問題
爲什麼編譯甚至同意編譯功能,而不返回聲明?傳統代碼需要此功能嗎?
爲什麼輸出取決於優化級別?
1.證明一個函數沒有返回所有路徑並不容易。 2.這是未定義的行爲,所以你不能指望任何特定的輸出。 – juanchopanza 2014-10-07 13:42:46
相關[爲什麼此C++代碼片段編譯(非void函數不返回值)](http://stackoverflow.com/q/20614282/1708801)。基本上,由於它是未定義的行爲,你的結果是不可預知的,編譯器在優化過程中利用UB而臭名昭着。在所有情況下很難察覺到這一點。 – 2014-10-07 13:42:59
你注意警告嗎?將-Werror標誌傳遞給gcc,它不會編譯。 – Slava 2014-10-07 13:48:52