Ale*_*x B 2 c++ visual-studio-2005
我遇到了以下编译良好的代码(使用Visual Studio 2005):
SomeObject SomeClass::getSomeThing()
{
for each (SomeObject something in someMemberCollection)
{
if ( something.data == 0 )
{
return something;
}
}
// No return statement here
}
Run Code Online (Sandbox Code Playgroud)
如果方法结尾没有return语句,为什么要编译?
Jar*_*Par 20
这是为了支持与C的向后兼容性,这并不严格要求从所有功能返回.在这些情况下,您只需留下返回位置(堆栈或寄存器)中的最后一个值.
如果这是在没有警告的情况下进行编译,尽管您可能没有将错误级别设置得足够高.大多数编译器现在会对此发出警告.
可以编写保证始终返回值的代码,但编译器可能无法解决这个问题.一个简单的例子是:
int func(int x)
{
if(x > 0)
return 1;
else if(x == 0)
return 0;
else if(x < 0)
return -1;
}
Run Code Online (Sandbox Code Playgroud)
就编译器而言,所有3个if语句都可以进行求值false,在这种情况下,控制将从函数末尾开始,返回未定义的结果.但是,在数学上,我们知道它不可能发生,所以这个函数定义了行为.
是的,一个更聪明的编译器可能能够解决这个问题,但想象一下整数比较,我们调用了在单独的转换单元中定义的外部函数.然后,作为人类,我们可以证明所有控制路径都返回值,但编译器肯定无法解决这个问题.
允许这样做的原因是为了与C兼容,并且C允许它的原因是为了与C标准化之前编写的传统C代码(ANSI之前的版本)兼容.有些代码确实如此,所以为了让这些代码保持有效和无错误,C标准允许这样做.但是,让控件在不返回值的情况下脱离函数仍然是未定义的行为.
任何体面的编译器都应该对此提出警告; 根据您的编译器,您可能必须提高警告级别.我相信gcc的这个警告的选项是-Wextra,其中还包括一堆其他警告.