当函数末尾缺少返回语句时,为什么它能工作
Why does it work when a function missing a return statement at the end?
我正在学习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语句。
但编译器表示没有错误,并且在执行时可以正常工作。
因此,我选取了一些特定的数字,如40
、44
、59
、61
,以查看函数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++标准的角度来看,您收到的代码警告(或错误)是可选的。这没关系,因为编译器可以自由地提供更多的输出,即使在不需要诊断消息的情况下也是如此。
顺便说一下。。。
它在执行时起作用。
这只是个巧合。未定义的行为意味着一切都可能发生,包括偶尔想要的行为。
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 为什么我的 std::ref 无法按预期工作?
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 有人能解释一下为什么下界是这样工作的吗C++的
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 为什么stream::忽略未按预期工作
- 为什么 HeapFree() 不能正常工作?
- 为什么我在 AVR 中的中断无法正常工作?
- 为什么指针在对二维数组进行排序时无法正常工作?
- 为什么C++需要公共继承,忽略朋友声明,才能使动态向下工作?
- 为什么 sizeof(ar)/ sizeof(ar[0]) 在传递给函数时无法在向量上正常工作?
- 为什么它在不分配内存的情况下工作正常
- 为什么重载运算符"="动态数组的类上无法正常工作?C++
- std::async 如何工作:为什么它会调用这么多次复制/移动?
- 为什么"std::is_function_v"不能按预期工作?
- if-else 语句仅按特定顺序工作,我不知道为什么
- 为什么我的 while 循环对于特定输入中断,而对于其他输入工作正常?
- 你能向我解释这段代码吗,为什么工作是 c++ 质数
- C++函数指针.它是如何工作的以及为什么工作
- Boost::Bind和虚函数重载:它们为什么工作?