如果没有end return语句,这个C ++代码如何编译?

时间:2009-09-09 17:22:46

标签: 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
}

如果方法结尾没有return语句,为什么要编译?

4 个答案:

答案 0 :(得分:20)

这是为了支持与C的向后兼容性,这并不严格要求从所有功能返回。在这些情况下,您只需留下返回位置(堆栈或寄存器)中的最后一个值。

如果这是在没有警告的情况下进行编译,尽管您可能没有将错误级别设置得足够高。大多数编译器现在都会对此发出警告。

答案 1 :(得分:5)

将警告级别设置为4并尝试。不是所有控制路径返回值都是我记得收到此警告的警告。

答案 2 :(得分:5)

可以编写保证始终返回值的代码,但编译器可能无法解决这个问题。一个简单的例子是:

int func(int x)
{
    if(x > 0)
        return 1;
    else if(x == 0)
        return 0;
    else if(x < 0)
        return -1;
}

就编译器而言,所有3个if语句都可以求值为false,在这种情况下,控制将从函数末尾开始,返回未定义的结果。但是,在数学上,我们知道这不可能发生,所以这个函数定义了行为。

是的,一个更聪明的编译器可能能够解决这个问题,但想象一下整数比较,我们调用了在单独的翻译单元中定义的外部函数。然后,作为人类,我们可以证明所有控制路径都返回值,但编译器肯定无法解决这个问题。

允许这样做的原因是为了与C兼容,并且C允许它的原因是为了与C标准化之前编写的传统C代码兼容(ANSI之前)。有些代码确实如此,所以为了让这些代码保持有效和无错误,C标准允许这样做。但是,让控件在不返回值的情况下脱离函数仍然是未定义的行为。

任何体面的编译器都应该对此提出警告;根据您的编译器,您可能必须提高警告级别。我相信gcc的这个警告选项是-Wextra,其中还包含一堆其他警告。

答案 3 :(得分:0)

可能你的特定编译器没有做到应有的好的流量控制分析。

您使用的是什么编译器版本以及您使用哪些开关进行编译?