为啥 main 的默认返回值为 0 而不是 EXIT_SUCCESS?
Posted
技术标签:
【中文标题】为啥 main 的默认返回值为 0 而不是 EXIT_SUCCESS?【英文标题】:Why default return value of main is 0 and not EXIT_SUCCESS?为什么 main 的默认返回值为 0 而不是 EXIT_SUCCESS? 【发布时间】:2010-11-14 08:55:16 【问题描述】:ISO 1998 c++ 标准规定,在 main 中不显式使用 return 语句等同于使用 return 0
。
但是,如果实现具有不同的标准“无错误”代码,例如 -1
,该怎么办?
为什么不使用标准宏 EXIT_SUCCESS
,它将被 0
或 -1
或任何其他值替换,具体取决于实现?
C++ 似乎强制了程序的语义,这不是一种只应描述程序行为方式的语言的角色。此外,“错误”返回值的情况有所不同:只有EXIT_FAILURE
是标准的“错误”终止标志,没有明确的值,例如“1”。
这些选择的原因是什么?
【问题讨论】:
【参考方案1】:从main()
返回零与您所要求的基本相同。从main()
返回零不必将零返回到主机环境。
来自 C90/C99/C++98 标准文档:
如果 status 的值为 0 或
EXIT_SUCCESS
,则返回实现定义的状态成功终止形式。
【讨论】:
只是为了澄清,这是为exit()函数指定的,3.6.1:5声明从main返回的效果是离开main然后调用exit()。所以,是的,你是对的。 :) 也就是说,0和EXIT_SUCCESS
是等价的返回值,所以标准要求默认返回哪一个都没有关系。
很有趣,这意味着c++标准不强制宿主“成功代码”。因此,从 c++ 程序返回“0”并不能保证主机系统将收到“0”,这意味着 c++ return 语句的行为可能与程序员指定的不同:“return 0”可能在实现上“替换”为“返回 1”?
@Serious - 请记住,特定环境甚至可能不像 Unix 那样使用数字返回码。如果今天有什么或多或少只是好奇心,我会感到惊讶,但例如,老实说,我不知道在使用 JCL 控制程序执行的大型机环境中会发生什么。
@Serious:但要更直接地回答您的问题 - 如果程序的执行环境期望 1 表示成功而 0 表示失败,那么 main() 中的“返回 0”可能应该设置程序的退出代码为 1。“返回 EXIT_FAILURE”可能应该将程序的退出代码设置为 0。但我希望这些环境非常少见,因为 C 和 Unix 将 0 解释为成功非常有影响力。【参考方案2】:
实际上,return 0
不一定会返回 0!我在这里引用 C 标准,因为这是我最了解的。
关于return
in main()
:
5.1.2.2.3 程序终止
如果主函数的返回类型是与
int
兼容的类型,则从初始调用main
函数返回相当于用main
返回的值调用exit
函数函数作为它的参数;
关于exit()
:
7.20.4.3 退出函数 概要
#include <stdlib.h> void exit(int status);
[...] 最后,控制权返回到主机环境。如果
status
的值为零或EXIT_SUCCESS
,状态成功终止的实现定义形式是 返回。
【讨论】:
总是很高兴看到有人以易于理解的方式解释标准。尽管如此,能够在文字零和 EXIT_SUCCESS 之间进行选择就相当于使用两个可能相互冲突的定义。我这样想对吗? 你从哪里看到这样的冲突?编译器有责任让它工作。最简单的方法是 #define EXIT_SUCCESS 0 但这只是一种选择。 @Bastien :谢谢,你们的 cmets 完成了 Michael 的解释。【参考方案3】:标准只是在未明确设置时确定必须是什么值。由开发人员明确设置返回值或为默认值假定适当的语义。我不认为该语言试图将任何语义强加给开发人员。
【讨论】:
默认值不应该由c++层决定,而是由系统决定。例如,如果一个程序最初是用 c++ 编写的,“0”将是标准的成功代码;然后,如果它用“1”是标准默认成功代码的其他语言重写,它将破坏使用它的其他程序/用户的行为。而如果这两种语言都有一个宏 EXIT_SUCCESS 将由主机系统管理,那么一切都会正常工作。宏将被编译器替换为系统上的值:“0”代表posix,“1”代表其他......【参考方案4】:0 是所有 POSIX 系统以及我所知道的所有系统上的标准(成功)退出代码!我认为从一开始就是这样(或者至少从 Unix 开始......)所以我会说这是出于这个原因。
你知道哪个系统不同?
【讨论】:
恕我直言,这不是问题所在:如果有任何 system 更喜欢不同的值,并且 language 定义了成功的主要返回值是什么,这会使该系统上的语言发生冲突。除此之外,你不能通过举例来证明一个定理。 “EXIT_STATUS 可能有一个不同于 0 的值,实际上它在 VAX/VMS 上的某个时间点确实如此”:取自 bytes.com/groups/c/215177-exit_success-guaranteed-always-zero 确实,“0”作为成功标志是“事实上的”标准。但是使其成为 c++ 的标准会迫使主机系统使用它,以便成为“符合 ISO 标准”的实现。而使用像 EXIT_SUCCESS 这样的标准常量可以保证语义“一切正常”与实现细节无关,“0 表示成功,1 表示失败......”。【参考方案5】:0 作为成功的返回码,正整数作为错误是 C 和 Unix 中的标准。之所以选择此方案,是因为通常人们并不关心程序成功的原因,只关心它成功了。另一方面,程序因错误而失败的方式有很多,人们通常对此信息感兴趣。因此,使用标量值表示成功,使用范围值表示错误是有意义的。使用正整数是一种节省内存的 C 约定,因为它们允许将错误代码定义为无符号整数。
【讨论】:
【参考方案6】:OS/360 和后续版本使用数字退出代码,0
通常表示成功,4
表示警告(例如生成警告消息的编译器),8
表示错误,12
表示特别糟糕错误
(如无法打开标准输出单元SYSPRINT)。
【讨论】:
【参考方案7】:计算机语言标准说明了用该语言编写的程序必须做什么以及会发生什么。在这种情况下,C 和 C++ 标准表示返回 0 表示成功等。
语言实现允许程序在特定实现上运行。实现者的工作是弄清楚如何使 I/O 工作符合标准,或者为操作系统提供正确的结果代码。
程序所做的和操作系统看到的不一定是同一件事。所需要的只是程序在给定的操作系统上按照标准所说的那样工作。
【讨论】:
【参考方案8】:通过浏览cstdlib
,我最终得到了两行:
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
所以EXIT_SUCCESS
等于0
,EXIT_FAILURE
等于1
,这意味着没关系,想想。
在 Linux (OpenSuse) 上检查并得到同样的结果。
【讨论】:
学究式:这些定义仅适用于您的平台,其他平台可以使用不同的约定;虽然我认为它们现在是通用的。 :) @Pragmateek 当然是。这段代码来自 Windows,但我认为它与 Linux 相同。不过,我会从 Linux 和 android 开始阅读,我们会看看我会以什么结尾。【参考方案9】:如果您还想知道为什么成功的错误代码是 0 而不是任何其他值,我会补充说,从历史上看,这可能是出于性能原因,因为与 0 相比要快得多(我认为在现代架构中可能与任何数字相同)并且通常您不会检查特定的错误代码,只要它是成功或任何错误(因此使用最快的比较是有意义的)。
【讨论】:
我不认为这是使用 0 作为成功指标的原因——我相信原因是通常有不止一种失败的方式,所以需要不止一种失败代码。 确实如此,但与我所说的并不矛盾。如果 ERROR_SUCCESS 为 1(或任何一个),您仍然可以使用所有其他数字来指示不同类型的故障。以上是关于为啥 main 的默认返回值为 0 而不是 EXIT_SUCCESS?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 binding.myTextView 返回一个 TextView?而不是 TextView
为啥 sizeof() 返回 4 个字节而不是 2 个字节的 short int? [复制]