当函数在结尾处缺少return语句时,为什么它可以工作?

时间:2015-11-06 13:38:22

标签: c++ function return

我正在学习C ++。下面的代码让我感到困惑:

int test_return(int a)
{
    for (int i = 40; i < 44; i++)
    {
        if (i == a)
        {
            cout << "return here with i: " << i << endl;
            return 59;
        }
    }
}

int main()
{
    cout << "in main: " << test_return(61) << endl;
    return 0;
}

我知道我在函数test_return的末尾缺少一个return语句。

但编译器说没有错误,它在执行时有效。

因此,我会选择一些特定的数字,例如40445961,以查看函数test_return将选择返回哪一个。

我试了几次,输出总是这样:

in main: 44

似乎函数test_return在for语句结束之前返回了int i

我的问题是:

这合法吗?

它是如何运作的?

更新:

我在函数test_return的末尾添加了这些代码:

int i = 100;
int square = i * i;

它出来了:

in main: 10000

感谢@Vlad来自莫斯科的回答!它会有所帮助。

2 个答案:

答案 0 :(得分:6)

如果有兼容英特尔的计算机,那么该函数似乎会将结果返回到寄存器EAX

同时该函数将此寄存器用于变量i。

因此循环后寄存器总是包含44。

此值接收来电者。

当然,该函数具有未定义的行为。它应该有一个显式的return语句,在循环之后的函数末尾有一个表达式。

答案 1 :(得分:2)

  

但编译器说没有错误,它在执行时有效。

这取决于您的警告级别。

例如,MSVC在使用/W1/W4之类的任何内容进行编译时说:

warning C4715: 'test_return' : not all control paths return a value

您甚至可以使用/WX选项将警告变为错误:

error C2220: warning treated as error - no 'object' file generated
warning C4715: 'test_return' : not all control paths return a value

GCC或其他编译器有类似的选择。只需阅读文档或研究Google中的选项。

C ++的理念是,如果他们不仔细考虑他们的编译器设置,使用低警告级别或忽略警告,那就是开发人员的错。如果您执行上述任何操作,那么结果通常是在运行时未定义的行为,就像您的情况一样(缺少返回值)。

您还应该知道C ++标准不区分错误和警告;它只知道所谓的“诊断信息”。编译器是否应将这些变为警告或错误并不是强制要求的。但是,缺少返回值不需要此类诊断消息。因此,从C ++标准的角度来看,您收到的代码警告(或错误)是可选的。没关系,因为即使在不需要诊断消息的情况下,编译器也可以自由提供更多输出。

顺便说一句......

  

执行时有效。

这只是一个巧合。未定义的行为意味着一切都会发生,包括不时出现的所需行为。