当函数末尾缺少返回语句时,为什么它能工作

Why does it work when a function missing a return statement at the end?

本文关键字:为什么 工作 语句 返回 函数      更新时间:2023-10-16

我正在学习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回复!这很有帮助。

如果有与英特尔兼容的计算机,则函数似乎会在寄存器EAX中返回结果。

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

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

此值接收调用者。

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

但编译器表示没有错误,并且在执行时可以正常工作。

这取决于您的警告级别。

例如,当使用从/W1/W4的任何内容进行编译时,MSVC会说:

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或其他编译器也有类似的选项。只需阅读文档或研究谷歌中的选项即可。

C++的原理是,如果开发人员没有仔细考虑编译器设置、使用低警告级别或忽略警告,那就是他们的错。如果你做了这些事情中的任何一件,那么结果通常是运行时未定义的行为,就像你的情况一样(缺少返回值)。

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

顺便说一下。。。

它在执行时起作用。

这只是个巧合。未定义的行为意味着一切都可能发生,包括偶尔想要的行为。