C函数定义为int但在正文中没有返回语句仍然编译

Nik*_*ita 16 c compilation

假设您有这样的C代码:

#include <stdio.h>

int main(){
    printf("Hello, world!\n");
    printf("%d\n", f());    
}

int f(){

}
Run Code Online (Sandbox Code Playgroud)

它用gcc编译好,输出(在我的系统上)是:

你好,世界!

14

但是......但是......这怎么可能?我认为C不会让你编译那样的东西因为f()没有返回整数的return语句.为什么允许这样做?它是C功能还是编译器遗漏,14来自何处?

Ada*_*erg 18

在这种情况下,返回值取决于确切的平台,可能是EAX在装配级别的返回寄存器(例如,在x86上)中遗留的任何随机值.不允许显式返回值,但会给出未定义的值.

在这种情况下,14是来自的返回值printf.

  • 从技术上讲,如果非`void`函数返回没有值*并且函数的返回值被使用*,则行为未定义(C99§6.9.1/ 12) - 它可能返回一个随机值,它可能会崩溃,在x86上,它可能只是使用EAX寄存器中的任何垃圾.但在其他架构上,例如IA64,[未初始化的垃圾可能是致命的](http://blogs.msdn.com/b/oldnewthing/archive/2004/01/19/60162.aspx). (8认同)

Ale*_*own 9

编译以-Wall在编译器中启用更多的健全性检查.

gcc -Wall /tmp/a.c
/tmp/a.c: In function ‘main’:
/tmp/a.c:5: warning: implicit declaration of function ‘f’
/tmp/a.c:6: warning: control reaches end of non-void function
/tmp/a.c: In function ‘f’:
/tmp/a.c:10: warning: control reaches end of non-void function
Run Code Online (Sandbox Code Playgroud)

注意它如何标记缺少的return语句 - 因为"控制到达非void函数的结尾"?

总是使用-Wall或类似程序进行编译 - 稍后您将为自己节省心痛.


我可以回想一下,当这个确切的问题导致几小时或几天的调试修复时,它可以回想起来 - 直到有一天它才会有效.