为什么main在这里不返回0?

我正在读书

ISO / IEC 9899:201x委员会草案 – 2011年4月12日

我在5.1.2.2.3中find程序终止

..reaching the } that terminates the main function returns a value of 0. 

这意味着如果你没有在main()指定任何返回语句,并且程序运行成功,那么main的右括号将返回0。

但是在下面的代码中,我没有指定任何返回语句,但它不返回0

 #include<stdio.h> int sum(int a,int b) { return (a + b); } int main() { int a=10; int b=5; int ans; ans=sum(a,b); printf("sum is %d",ans); } 

 gcc test.c ./a.out sum is 15 echo $? 9 // here it should be 0 but it shows 9 why? 

该规则是在1999年的C标准版本中增加的。 在C90中,返回的状态是未定义的。

您可以通过将-std=c99传递给gcc来启用它。

作为一个方面说明,有趣的是9返回,因为它是只写了9个字符的printf的返回值。

它返回printf返回值,它是真正打印出来的字符的个数。

函数的返回值通常存储在cpu的eax寄存器中,所以语句“return 4;” 通常会编译成

 mov eax, 4; ret; 

并返回x(取决于你的编译器)会是这样的:

 mov eax, [ebp + 4]; ret; 

如果你没有指定返回值,那么编译器仍然会吐出“ret”,但不会改变eax的值。 所以调用者会认为以前留在eax寄存器中的是返回值。 在这个例子中,它通常是返回值printf,但不同的编译器会生成不同的机器代码,并使用一些不同的寄存器。

这是一个简单的解释,不同的调用约定和目标平台将起到至关重要的作用,但是应该有足够的信息来解释你的例子中“幕后”发生的事情。

如果你对汇编器有一个基本的了解,那么比较不同编译器的反汇编就是值得的。 你可能会发现有些编译器正在清除eax寄存器作为一种保护措施。