在`main`可选的结尾处使`return 0`的理由是什么?

从C99标准开始,如果在main的末尾没有提供return EXIT_SUCCESS ,则编译器需要生成等效的return 0return EXIT_SUCCESS 。 在同一时间,对C ++语言标准也进行了相应且相同的更改。 我对两者的原因感兴趣,并且我猜测它们不太可能是完全独立且无关的变化。

我的问题是:

这种变化的记录理由是什么?

一个理想的答案将引用C和C ++的权威来源,这就是我用两种语言标记问题的原因。

请注意,与问题不同, 在ISO C ++中从main返回0的原因是什么? ,我不是在寻求关于是否在我的程序中写return 0建议 – 我在问为什么语言标准本身已经改变了。


为了帮助理解问题的目的,这里有更多的背景:

  1. 了解更改的原因有助于决定如何使用它。
  2. 理由通常包含在标准本身中。 例如,C90标准包括许多解释性脚注,例如脚注36,其开头是“此列表的意图……”

在我问到这个问题之前,我已经研究了自己寻找答案的标准,但没有找到答案。 我被要求帮助为一组程序员编写两种语言的编码标准,我想确保我理解为什么这个function存在,以便我可以准确地向其他人解释它的使用。

在新C标准部分5.1.2.2.3程序终止作者Derek Jones对C99标准中的这一行的评论:

到达终止main函数的}返回值0

是:

标准最终不得不屈服于现有的做法。

这表明理由是解决关于从main显式返回值的糟糕编程实践。 在此之前,返回的状态未定义。

他指出,即使在C90中,许多实现已经实现了这一点,因此这种变化已经反映了常见的实现也可能有所帮助。

C99的官方理由文件几乎没有解决这个问题。 看来exit(0)成为main结束时控制流的默认值,因为exit(0)被赋予了有意义的可移植语义。

以下是两个相关部分:

5.1.2.2.1程序启动

main的参数行为以及exitmainatexit的相互作用(参见§7.20.4.2)已被编纂,以遏制argv字符串表示中的一些不需要的变化,以及main返回的值的含义

argcargv作为argc参数的规范认可了广泛的先前实践。

argv[argc]必须是一个空指针,以便在列表末尾提供冗余检查,同样基于通常的做法。

main是唯一可以使用零或两个参数进行声明的函数。 (其他函数参数的数量必须在调用和定义之间完全匹配。)这种特殊情况简单地认识到当程序不访问程序参数字符串时,将参数遗漏给main的普遍做法。 虽然许多实现支持main两个以上的参数,但这种做法既没有被标准祝福也没有被禁止; 用三个参数定义main的程序并不严格符合(参见§J.5.1。)。

标准不强制命令行I / O重定向,因为这被认为是底层操作系统而不是C语言的一个特性。

7.20.4.3退出function

exit的参数是返回到调用环境的状态指示。 在UNIX操作系统中,值为零是程序的成功返回代码。 由于C的使用已经扩展到UNIX之外 ,因此即使在具有不同返回代码系统的操作系统上exit(0)也经常被保留为表示成功终止的习语 。 因此,该用法被认为是标准的。 从来没有一种表示非成功终止的可移植方式,因为exit的参数是实现定义的。 EXIT_FAILURE宏已添加到C89以提供此类function。 EXIT_SUCCESS也被添加了。

除了由程序员显式编码的调用之外,从main返回时调用exit 。 因此,至少在这种情况下, exit体不能假设存在具有自动存储持续时间的任何物体,除了在exit声明的物体。

委员会考虑添加_exit ,但基于与其所基于的POSIX规范不兼容的问题拒绝了它。 例如,表达的一个问题是_exit被指定为一种在不触发另一个信号的情况下离开信号处理程序的方法,但这实际上并不是_exit在POSIX环境中的行为方式。 委员会不希望给程序员这种虚假的希望。 (但参见C99的§7.20.4.4。)