Jee*_*tel 116 c linux program-entry-point return
我只是在读书
ISO/IEC 9899:201x委员会草案 - 2011年4月12日
我在5.1.2.2.3程序终止下找到了
..reaching the } that terminates the main function returns a value of 0.
Run Code Online (Sandbox Code Playgroud)
这意味着如果你没有指定任何return语句main()
,并且如果程序成功运行,那么在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);
}
Run Code Online (Sandbox Code Playgroud)
编
gcc test.c
./a.out
sum is 15
echo $?
9 // here it should be 0 but it shows 9 why?
Run Code Online (Sandbox Code Playgroud)
cni*_*tar 140
该规则在1999年版的C标准中添加.在C90中,返回的状态未定义.
您可以通过传递-std=c99
给gcc 来启用它.
作为旁注,有趣的是9返回,因为它的返回printf
只写了9个字符.
函数的返回值通常存储在cpu的eax寄存器中,因此语句"return 4;" 通常会编译为
mov eax, 4;
ret;
Run Code Online (Sandbox Code Playgroud)
并返回x(取决于您的编译器)将是这样的:
mov eax, [ebp + 4];
ret;
Run Code Online (Sandbox Code Playgroud)
如果你没有指定返回值,那么编译器仍然会吐出"ret"但不会改变eax的值.因此调用者会认为之前留在eax寄存器中的是返回值.对于此示例,它通常是返回值printf,但不同的编译器将生成不同的机器代码并以不同方式使用某些寄存器.
这是一个简化的解释,不同的调用约定和目标平台将发挥至关重要的作用,但它应该足以解释您的示例中"幕后"发生的事情.
如果您对汇编程序有基本的了解,那么有必要比较不同编译器的反汇编.您可能会发现某些编译器正在清除eax寄存器作为安全措施.