程序的退出代码为空 void main() 是什么意思?

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

255here的含义是什么,为什么它会被在 main() 之前或之后执行的任何代码返回?如果我使用 int main() 并且不放置 return 语句,退出代码为零。

Joh*_*ger 5

这里的25和5是什么意思

C 语言规范没有定义main()声明为 return的程序的行为void。尽管如此,接受此类代码的实现可能会或可能不会为其定义行为。在一般意义上,然后,没有退出状态有一个与程序的任何意义或意义void main()

显然,特别是 GCC 确实接受了该代码,但我在GCC 的记录 C 扩展中没有找到其行为的定义,因此在这种特殊情况下,您观察到的退出状态没有任何意义。

为什么它会被在 main() 之前或之后执行的任何代码返回?

没有特别的理由。行为未定义。

如果我使用 int main() 并且不放置 return 语句,退出代码为零。

这种情况定义得很清楚。C 指定如果执行到达初始调用的末尾main()(假定使用两个 C 标准签名之一声明,两者都返回int),则行为就像exit(0)被调用一样。这是一个特例。如果执行到达非void函数的右大括号,并且其调用者对返回值执行任何操作,则行为未定义。


man*_*lio 5

(添加约翰·博林格的回答)

\n\n

* 无效主

\n\n

旧的 ISO C 标准 (ISO/IEC 9899:1999) 规定:

\n\n
\n

[主要] 应定义

\n\n
    \n
  • 返回类型为intand\n \n
      \n
    • 不带参数 [\xe2\x80\xa6] 或
    • \n
    • 有两个参数 [\xe2\x80\xa6] 或等效参数;\n 或
    • \n
    • 以其他一些实现定义的方式。
    • \n
  • \n
\n
\n\n

\xc2\xa7 5.1.2.2.1 C 标准的 \xc2\xb6 1

\n\n
\n

如果返回类型与 不兼容int,则返回到主机环境的终止状态是未指定的。

\n
\n\n

\xc2\xa7 5.1.2.2.3 \xc2\xb6 1

\n\n

这表明允许未返回的表单int是故意的。

\n\n

许多编译器手册(例如Watcom C/C++、IBM VisualAge C/C++、Microsoft Visual C/C++)都指出可能main具有返回类型void,因此具有返回类型的程序void main()是符合要求的程序。

\n\n

很长一段时间以来,许多代码都是使用返回类型编写的voidgcc(可能)认为与遗留代码兼容很重要并允许,void main()但在这种情况下:

\n\n
    \n
  • 它给出警告(warning: return type of \xe2\x80\x98main\xe2\x80\x99 is not \xe2\x80\x98int\xe2\x80\x99);
  • \n
  • 程序的返回值未定义。
  • \n
\n\n

参考:

\n\n\n\n

* int 主函数

\n\n

int main() {}

\n\n

这在 C89/90 中未定义,但在以下版本中定义良好(返回0)。

\n\n

* 实际价值

\n\n

在 x86 上,EAX寄存器通常用于返回值。所以

\n\n
int main() {}\n
Run Code Online (Sandbox Code Playgroud)\n\n

被编译为类似:

\n\n
main:\n        push    rbp\n        mov     rbp, rsp\n        mov     eax, 0\n        pop     rbp\n        ret\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了

\n\n
void main() {}\n
Run Code Online (Sandbox Code Playgroud)\n\n

最简单的操作是删除mov eax, 0

\n\n
main:\n        push    rbp\n        mov     rbp, rsp\n        nop\n        pop     rbp\n        ret\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果添加一条printf语句:

\n\n
#include <stdio.h>\n\nvoid main()\n{\n  printf("1234");\n}\n
Run 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\n
Run Code Online (Sandbox Code Playgroud)\n\n

printf调用更改EAX寄存器(返回写入流的字符数,并EAX用作返回值)。

\n