假设你用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