这是一个简单的问题,但我一直看到相互矛盾的答案:C++ 程序的主例程应该返回 0
还是 EXIT_SUCCESS
?
#include <cstdlib>
int main(){return EXIT_SUCCESS;}
或者
int main(){return 0;}
它们是完全一样的吗? EXIT_SUCCESS
应该只与 exit()
一起使用吗?
我认为 EXIT_SUCCESS
会是一个更好的选择,因为其他软件可能希望将零视为失败,但我还听说如果您返回 0
,编译器无论如何都能够将其更改为不同的值。
EXIT_FAILURE
,无论是在 main
中的 return 语句中还是作为 exit()
的参数,都是在 C 或 C++ 程序中指示失败的唯一可移植方式。例如,exit(1)
实际上可以表示 VMS 上的成功终止。
如果您要在程序失败时使用 EXIT_FAILURE
,那么您不妨在程序成功时使用 EXIT_SUCCESS
,只是为了对称。
另一方面,如果程序从不发出失败信号,您可以使用 0
或 EXIT_SUCCESS
。标准保证两者都表示成功完成。 (EXIT_SUCCESS
几乎不可能有 0 以外的值,但在我听说过的每个实现中它都等于 0。)
使用 0
有一个次要优势,即您在 C 中不需要 #include <stdlib.h>
或在 C++ 中不需要 #include <cstdlib>
(如果您使用 return
语句而不是调用 exit()
)——但对于程序无论如何,您将直接或间接地包含任何显着大小的stdlib。
就此而言,在从 1999 年标准开始的 C 以及所有版本的 C++ 中,到达 main()
的末尾无论如何都会隐含 return 0;
,因此您可能不需要显式使用 0
或 EXIT_SUCCESS
. (但至少在 C 语言中,我认为明确的 return 0;
是更好的风格。)
(有人问起 OpenVMS。我很久没有使用它了,但我记得奇数状态值通常表示成功,偶数值表示失败。C 实现将 0
映射到 1
,因此 return 0;
表示成功终止。其他值不变传递,因此 return 1;
也表示成功终止。EXIT_FAILURE
将具有非零偶数值。)
不要紧。两者都是一样的。
C++ 标准行情:
如果 status 的值为零或 EXIT_SUCCESS,则返回实现定义的状态成功终止形式。
EXIT_SUCCESS == 0
。另一方面,没有充分的理由不这样做。
根据定义,0 是一个幻数。 EXIT_SUCCESS 几乎普遍等于 0,很高兴。那么为什么不直接返回/退出 0 呢?
退出(EXIT_SUCCESS);含义非常明确。
退出(0);另一方面,在某些方面是违反直觉的。不熟悉 shell 行为的人可能会认为 0 == false == 不好,就像 C 中 0 的所有其他用法一样。但不是 - 在这种特殊情况下,0 == 成功 == 好。对于大多数有经验的开发人员来说,这不会成为问题。但是为什么完全没有理由绊倒新人呢?
tl; dr - 如果您的幻数有一个定义的常量,那么几乎没有理由不首先使用该常量。它更易于搜索,通常更清晰等,并且不会花费您任何费用。
fclose()
, setvbuf()
, ...), POSIX (listen()
, pthread_create()
, pipe()
, ...), and many, many< /b> 其他库(例如 OpenGL [glGetError()
]、zlib [deflate()
/inflate()
/...]、SDL [SDL_CreateWindowAndRenderer()
/...] 等)。
这是一个永无止境的故事,反映了“互操作性和可移植性”的局限性(一个神话)。
程序应该返回什么来表示“成功”应该由接收值的人(操作系统或调用程序的进程)定义,而不是由语言规范定义。
但是程序员喜欢以“可移植方式”编写代码,因此他们为定义要返回的符号值的“操作系统”概念发明了自己的模型。
现在,在多对多场景中(许多语言用于向许多系统编写程序),“成功”的语言约定与操作系统之间的对应关系(没有人可以允许始终相同)应该由特定目标平台的库的特定实现来处理。
但是 - 不幸的是 - 这些概念在部署 C 语言时并不那么清楚(主要是为了编写 UNIX 内核),以及写成“返回 0 表示成功”的书籍的千兆克,因为这在操作系统上是正确的那个时候有一个 C 编译器。
从那时起,对于如何处理此类通信,就再也没有明确的标准。 C 和 C++ 对“返回值”有自己的定义,但没有人授予正确的操作系统翻译(或者更好的是:没有编译器文档对此有任何说明)。 0 表示成功,如果对于 UNIX - LINUX 和 - 出于独立原因 - 对于 Windows 也是如此,这涵盖了 90% 的现有“消费者计算机”,在大多数情况下 - 忽略返回值(所以我们可以讨论了几十年,但没有人会注意到!)
在这种情况下,在做出决定之前,请问以下问题: - 我是否有兴趣与我的来电者交流我现有的信息? (如果我总是返回 0 ......所有事情背后都没有任何线索) - 我的来电者是否有关于这种沟通的约定? (请注意,单个值不是约定:不允许任何信息表示)
如果这两个答案都不是,那么好的解决方案可能是根本不编写主要的 return 语句。 (并让编译器来决定,相对于目标是如何工作的)。
如果没有约定,则 0=成功满足大多数情况(如果符号引入约定,则使用符号可能会有问题)。
如果约定到位,请确保使用与其一致的符号常量(并确保平台之间的约定一致,而不是价值一致)。
一旦您开始编写可以返回无数退出状态的代码,您就可以开始#define
处理所有这些状态。在这种情况下,EXIT_SUCCESS
在不是“magic number”的上下文中是有意义的。这使您的代码更具可读性,因为其他所有退出代码都是 EXIT_SOMETHING
。如果您只是编写一个完成后将返回的程序,那么 return 0
是有效的,并且可能更简洁,因为它表明没有复杂的返回代码结构。
你从一个程序返回的只是一个约定。
不,我想不出“EXIT_SUCCESS”不会是“0”的任何情况。
就个人而言,我推荐“0”。
恕我直言...
0
为假,许多函数在失败/什么都不做时返回 0
。
tl;博士:你不能返回任何东西。
ok(Bjarne Stroustrup 这么说...)不明确地从 main()
函数返回任何内容。如果您的操作系统需要返回值,编译器会小心处理。
这并不是要偏离 @KeithThompson 或 @EmilioGaravaglia 的答案中关于不同可能返回值的情况的讨论,以及了解如何解释程序的返回值等。
如果您使用 EXIT_SUCCESS,您的代码将更具可移植性。
http://www.dreamincode.net/forums/topic/57495-return-0-vs-return-exit-success/
EXIT_SUCCESS
都表示成功终止。
EXIT_FAILURE
,您的代码将更具可移植性”,那将是正确的。
一些编译器可能会对此产生问题 - 在 Mac C++ 编译器上,EXIT_SUCCESS 对我来说工作得很好,但在 Linux C++ 编译器上,我必须添加 cstdlib 才能知道 EXIT_SUCCESS 是什么。除此之外,它们是一回事。
EXIT_SUCCESS
在不包含 <stdlib.h>
或 <cstdlib>
的情况下工作,则必须有其他标头直接或间接定义了它。在 C++ 中,标准头文件到 #include
其他标准头文件是很常见的。如果编译没有错误:int main() { return EXIT_SUCCESS; }
那么你的编译器可能有问题。
不定期副业成功案例分享
exit(0)
映射到退出状态 1 时,怎么可能为 OpenVMS 实现 POSIX 实用程序? (如果我正确理解你的最后一段)0
和EXIT_SUCCESS
具有相同的值(我在回答中提到过),但它们都表示成功终止。EXIT_SUCCESS
在风格上更好如果您也在使用EXIT_FAILURE
,但exit(0)
没问题。EXIT_SUCCESS==0
。 (并且您不需要在return
语句上加上括号。就我个人而言,我认为它们使它看起来太像函数调用了。)