Mah*_*35h 1 c linux shell gcc exit-code
我制作了一个简单的 C 程序,其中的 main 为空,如下所示,并用 gcc 编译它
void main(){
}
Run Code Online (Sandbox Code Playgroud)
执行时,它返回退出代码为25,如果我添加一个 printf 语句,在包含 stdio.h 后,它返回退出代码5
25和5here的含义是什么,为什么它会被在 main() 之前或之后执行的任何代码返回?如果我使用 int main() 并且不放置 return 语句,退出代码为零。
这里的25和5是什么意思
C 语言规范没有定义main()声明为 return的程序的行为void。尽管如此,接受此类代码的实现可能会或可能不会为其定义行为。在一般意义上,然后,没有退出状态有一个与程序的任何意义或意义void main()。
显然,特别是 GCC 确实接受了该代码,但我在GCC 的记录 C 扩展中没有找到其行为的定义,因此在这种特殊情况下,您观察到的退出状态没有任何意义。
为什么它会被在 main() 之前或之后执行的任何代码返回?
没有特别的理由。行为未定义。
如果我使用 int main() 并且不放置 return 语句,退出代码为零。
这种情况定义得很清楚。C 指定如果执行到达初始调用的末尾main()(假定使用两个 C 标准签名之一声明,两者都返回int),则行为就像exit(0)被调用一样。这是一个特例。如果执行到达非void函数的右大括号,并且其调用者对返回值执行任何操作,则行为未定义。
(添加约翰·博林格的回答)
\n\n旧的 ISO C 标准 (ISO/IEC 9899:1999) 规定:
\n\n\n\n\n[主要] 应定义
\n\n\n
\n- 返回类型为
\nintand\n \n\n
- 不带参数 [\xe2\x80\xa6] 或
\n- 有两个参数 [\xe2\x80\xa6] 或等效参数;\n 或
\n- 以其他一些实现定义的方式。
\n
\xc2\xa7 5.1.2.2.1 C 标准的 \xc2\xb6 1
\n\n\n\n\n如果返回类型与 不兼容
\nint,则返回到主机环境的终止状态是未指定的。
\xc2\xa7 5.1.2.2.3 \xc2\xb6 1
\n\n这表明允许未返回的表单int是故意的。
许多编译器手册(例如Watcom C/C++、IBM VisualAge C/C++、Microsoft Visual C/C++)都指出可能main具有返回类型void,因此具有返回类型的程序void main()是符合要求的程序。
很长一段时间以来,许多代码都是使用返回类型编写的void。gcc(可能)认为与遗留代码兼容很重要并允许,void main()但在这种情况下:
warning: return type of \xe2\x80\x98main\xe2\x80\x99 is not \xe2\x80\x98int\xe2\x80\x99);参考:
\n\n\n\nint main() {}
这在 C89/90 中未定义,但在以下版本中定义良好(返回0)。
在 x86 上,EAX寄存器通常用于返回值。所以
int main() {}\nRun Code Online (Sandbox Code Playgroud)\n\n被编译为类似:
\n\nmain:\n push rbp\n mov rbp, rsp\n mov eax, 0\n pop rbp\n ret\nRun Code Online (Sandbox Code Playgroud)\n\n为了
\n\nvoid main() {}\nRun Code Online (Sandbox Code Playgroud)\n\n最简单的操作是删除mov eax, 0:
main:\n push rbp\n mov rbp, rsp\n nop\n pop rbp\n ret\nRun Code Online (Sandbox Code Playgroud)\n\n如果添加一条printf语句:
#include <stdio.h>\n\nvoid main()\n{\n printf("1234");\n}\nRun Code Online (Sandbox Code Playgroud)\n\n你得到:
\n\n.LC0:\n .string "1234"\nmain:\n push rbp\n mov rbp, rsp\n mov edi, OFFSET FLAT:.LC0\n mov eax, 0\n call printf\n pop rbp\n ret\nRun Code Online (Sandbox Code Playgroud)\n\n该printf调用更改EAX寄存器(返回写入流的字符数,并EAX用作返回值)。