如果没有明确的“返回”,则函数将返回什么

当我忘记编写函数的return子句时,我遇到了这个问题,但是gcc没有警告或错误。 我修复了它,但开始想知道为什么函数会在没有return情况下return 无意义的东西。 以下是我尝试过的一些例子:

 #include "stdio.h" #include "stdlib.h" int func1 () { int i; i = 2; } int func2 (int a) { int i = a+3; } int func3 () { int i; for (i = 0; i <= 1; i++); } int main(void) { int a = 0; int b = 0; int c = 0; a = func1(); printf("a = %d \n", a); b = func2(a); printf("b = %d \n", b); c = func3(); printf("c = %d \n", c); } 

结果是:

 a = 1 b = 4 c = 7 

我的问题:

1)为什么这些结果? 这有什么一般规则吗?
2)为什么要保留这个东西而不是报告错误? 在某个地方可以某种程度上“有用”吗?

这是未定义的行为 ,将取决于所使用的调用约定 。 如果调用者期望寄存器中的结果,那么将使用寄存器中最后的值。

编辑

6.9.1function定义12段中的C99标准草案说:

如果到达终止函数的},并且调用者使用函数调用的值,则行为是未定义的。

clang默认会发出警告, gcc会用-Wall发出警告,一般来说你应该启用警告。

根据第6.9.1节第12段(C标准的N1570草案),这是不明确的行为:

如果到达终止函数的} ,并且调用者使用函数调用的值,则行为是未定义的。

如果调用者未使用返回值,则行为不是未定义的。

仅仅未定义的行为不需要诊断消息,因此编译器没有义务发出警告。 如果你问它( -Wreturn-type ,由-Wall暗示),gcc会发出警告,并且默认情况下clang会发出警告。

对于返回void以外的类型的函数, return语句必须包含一个表达式,其值应根据6.8.6.4第1段返回:

带有表达式的return语句不应出现在返回类型为void的函数中。 不带表达式的return语句只能出现在返回类型为void的函数中。

在我的系统(gcc 4.5.3,linux)上,没有优化编译你的代码,我得到了这个:

 main: ... call func1 movl %eax, 28(%esp) ... 

func1的返回值是从eax寄存器中提取的,但该寄存器永远不会在func1设置,因此返回值是调用该函数时该寄存器中发生的任何事情。