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

时间:2011-12-30 08:40:15

标签: c linux return main

我刚读完

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

我在5.1.2.2.3程序终止

下找到了
..reaching the } that terminates the main function returns a value of 0. 

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

但是在下面的代码中我没有指定任何return语句,但它没有返回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?

3 个答案:

答案 0 :(得分:140)

该规则已在1999版C标准中添加。在C90中,返回的状态未定义。

您可以将-std=c99传递给gcc。

来启用它

作为旁注,有趣的是返回9,因为它是printf的返回,它只写了9个字符。

答案 1 :(得分:15)

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

答案 2 :(得分:6)

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

mov eax, 4;
ret;

并返回x(取决于您的编译器)将类似于:

mov eax, [ebp + 4];
ret;

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

这是一个简化的解释,不同的调用约定和目标平台将发挥至关重要的作用,但它应该足以解释您的示例中“幕后”发生的事情。

如果您对汇编程序有基本的了解,那么比较不同编译器的反汇编是值得的。您可能会发现某些编译器正在清除eax寄存器作为安全措施。