我已经在gcc中成功编译并执行了以下代码:
#include <stdio.h>
int foo()
{
}
int main()
{
int i = 12345;
i = foo();
printf("i is: %d", i);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
i is: 0
Run Code Online (Sandbox Code Playgroud)
所以gcc允许我不从函数返回foo()并foo()返回0.
这种行为只适用于gcc还是其他C标准也有它(基于我的理解,gcc不符合任何C标准)?
sep*_*p2k 10
如果函数缺少return语句¹,则没有C标准要求编译器产生错误或警告.
在所有C标准中,如果控制流在没有a return的情况下到达非void函数的末尾,则行为是未定义的,然后使用函数的返回值(如在代码中).
因此,如果"允许"意味着"将其指定为合法,定义明确的行为",那么C标准都不允许您的代码.如果你的意思是"不需要实现来产生错误",那么所有这些都可以.
请注意,i如果更改foo(不添加a return)的定义,示例程序中的值可以轻松更改.你不能依赖它为0.没有规则说"如果没有回报,则返回0" - 既不是标准也不是GCC的实施.根据标准,它是未定义的,在GCC中它只是当时在返回寄存器中发生的任何事情.
¹在一般情况下,这将是不可判定的.可以做一些例如Java所做的事情并定义规则,以便拒绝一些其他有效的函数定义,但没有一个C标准这样做.
gcc确实发出警告:
警告:控制到达非空函数的末尾[-Wreturn-type] |
(免责声明:我从不同版本的gcc得到不同的结果.确定,编译-Wall -Wextra -pedantic-errors.)
在这种情况下发生的事情不包括在C标准中.标准只是说(C11 6.9.1/12):
如果到达终止函数的},并且调用者使用函数调用的值,则行为是未定义的.
在您的情况下,调用者通过存储它来使用返回值i.所以这是未定义的行为 - C标准不包含该行为,编译器没有义务通知您.什么事情都可能发生.因此,在大多数情况下,这应该被视为一个错误.
好的,该标准中没有任何内容可以阻止您编写非法代码,但是,它确实提到了这是未定义的行为。
引用C11第6.9.1章
如果达到
}了终止函数的,并且调用者使用了函数调用的值,则行为是不确定的。