简体   繁体   English

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

[英]what's the meaning of exit code of program with empty void main()?

I made a simple C program with empty main as given below and compiled it with gcc我制作了一个简单的 C 程序,如下所示,主程序为空,并用 gcc 编译

void main(){
}

upon execution, it return exit code as 25 , and if I add a printf statement,after including stdio.h, it returns exit code 5执行时,它返回退出代码为25 ,如果我添加一个 printf 语句,包含 stdio.h 后,它返回退出代码5

what's the meaning of 25 and 5 here and why it's being returned by whatever code that is executed before or after main()?这里的255是什么意思,为什么在 main() 之前或之后执行的任何代码都会返回它? exit code is zero if I use int main() and don't put a return statement.如果我使用 int main() 并且不放置 return 语句,则退出代码为零。

what's the meaning of 25 and 5 here这里的 25 和 5 是什么意思

The C language specifications do not define behavior for a program whose main() is declared to return void . C 语言规范没有定义main()被声明为返回void的程序的行为。 Implementations that nevertheless accept such code may or may not define behavior for it.尽管如此,接受此类代码的实现可能会或可能不会为其定义行为。 In a general sense, then, no exit statuses have any meaning or significance for a program with void main() .因此,在一般意义上,退出状态对于具有void main()的程序没有任何意义或意义。

Apparently, GCC in particular does accept the code, but I find no definition for its behavior among GCC's documented C extensions , so neither in that particular case do the exit statuses you observe have any meaning.显然, GCC 确实接受了该代码,但我在GCC 记录的 C extensions中找不到其行为的定义,因此在这种特殊情况下,您观察到的退出状态都没有任何意义。

and why it's being returned by whatever code that is executed before or after main()?以及为什么在 main() 之前或之后执行的任何代码都会返回它?

No particular reason.没有特别的原因。 The behavior is undefined.行为未定义。

exit code is zero if I use int main() and don't put a return statement.如果我使用 int main() 并且不放置 return 语句,则退出代码为零。

That case is well defined.那个案子是很好定义的。 C specifies that if execution reaches the end of the initial call to main() (presumed declared with one of the two C-standard signatures, both of which return int ) then the behavior is as if exit(0) were called. C 指定如果执行到达对main()的初始调用结束(假定使用两个 C 标准签名之一声明,两者都返回int ),那么行为就像调用了exit(0)一样。 This is a special case.这是一个特例。 The behavior is otherwise undefined if execution reaches the closing brace of a non- void function, and its caller does anything with the return value.如果执行到达非void function 的右大括号,并且其调用者对返回值执行任何操作,则行为未定义。

(Adding on John Bollinger's answer) (添加约翰·布林格的回答)

* void main * 无效的主要

The old ISO C Standard (ISO/IEC 9899:1999) stated:旧的 ISO C 标准 (ISO/IEC 9899:1999) 规定:

[main] shall be defined [main] 应被定义

  • with a return type of int and返回类型为int
    • with no parameters […] or没有参数 […] 或
    • with two parameters […] or equivalent;带有两个参数 […] 或等效参数; or或者
    • in some other implementation-defined manner.以其他一些实现定义的方式。

§ 5.1.2.2.1 ¶ 1 of the C Standard § 5.1.2.2.1 ¶ 1 C 标准

If the return type is not compatible with int , the termination status returned to the host environment is unspecified.如果返回类型与int不兼容,则返回给宿主环境的终止状态是未指定的。

§ 5.1.2.2.3 ¶ 1 § 5.1.2.2.3 ¶ 1

which indicates that allowing forms that didn't return int was intentional.这表明允许不返回int的 forms 是故意的。

Many compiler's manuals (eg Watcom C/C++, IBM VisualAge C/C++, Microsoft Visual C/C++) stated that main may have the return type void so a program with void main() was a conforming program.许多编译器手册(例如 Watcom C/C++、IBM VisualAge C/C++、Microsoft Visual C/C++)声明main可能具有返回类型void ,因此具有void main()的程序是符合标准的程序。

For a long time much code was written with a return type of void .很长一段时间以来,很多代码都是用void返回类型编写的。 gcc (probably) consider important to be compatible with legacy code and allows void main() but in that case: gcc (可能)认为与遗留代码兼容很重要并允许void main()但在这种情况下:

  • it gives a warning ( warning: return type of 'main' is not 'int' );它发出警告( warning: return type of 'main' is not 'int' );
  • the return value of the program is undefined.程序的返回值未定义。

References:参考:

* int main * int 主要

int main() {}

This is undefined in C89/90 and well defined in following versions (where it returns 0 ).这在 C89/90 中是未定义的,并且在以下版本中定义良好(它返回0 )。

* actual value * 实际价值

On x86 the EAX register is normally used for return values.在 x86 上, EAX寄存器通常用于返回值。 So所以

int main() {}

is compiled to something like:被编译成类似的东西:

main:
        push    rbp
        mov     rbp, rsp
        mov     eax, 0
        pop     rbp
        ret

For为了

void main() {}

the simplest action is removing mov eax, 0 :最简单的操作是删除mov eax, 0

main:
        push    rbp
        mov     rbp, rsp
        nop
        pop     rbp
        ret

If you add a printf statement:如果添加printf语句:

#include <stdio.h>

void main()
{
  printf("1234");
}

you get:你得到:

.LC0:
        .string "1234"
main:
        push    rbp
        mov     rbp, rsp
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        pop     rbp
        ret

The printf call alters the EAX register (returns the number of characters written to the stream, and EAX is used for the return value). printf调用更改EAX寄存器(返回写入 stream 的字符数, EAX用于返回值)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM