我应该使用exit()
还是只使用return
语句main()
?就我个人而言,我喜欢这些return
陈述,因为我觉得它就像阅读任何其他函数一样,并且当我阅读代码时流程控制很流畅(在我看来)。即使我想重构main()
函数,拥有return
似乎比exit()
.
做一些没有exit()
做的特别的事情return
吗?
我应该使用exit()
还是只使用return
语句main()
?就我个人而言,我喜欢这些return
陈述,因为我觉得它就像阅读任何其他函数一样,并且当我阅读代码时流程控制很流畅(在我看来)。即使我想重构main()
函数,拥有return
似乎比exit()
.
做一些没有exit()
做的特别的事情return
吗?
其实还是 有区别的,但是很微妙。它对 C++ 有更多的影响,但差异很重要。
当我调用return
时main()
,将为我的本地范围对象调用析构函数。如果我调用exit()
,则不会为我的本地范围对象调用析构函数!再读一遍。exit()
不返回。这意味着,一旦我称它为,就“没有后盾”。您在该函数中创建的任何对象都不会被销毁。通常这没有任何影响,但有时确实如此,例如关闭文件(您肯定希望所有数据都刷新到磁盘吗?)。
请注意,static
即使您调用exit()
. 最后请注意,如果您使用abort()
,则不会销毁任何对象。也就是说,不会调用全局对象、静态对象和局部对象的析构函数。
在倾向于退出而不是返回时要谨慎行事。
http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a
另一个区别:
exit
是标准库函数,因此您需要包含标头并与标准库链接。为了说明(在 C++ 中),这是一个有效的程序:
int main() { return 0; }
但要使用exit
你需要一个包括:
#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }
另外,这增加了一个额外的假设:调用exit
frommain
与返回零具有相同的副作用。正如其他人指出的那样,这取决于您正在构建什么样的可执行文件(即,谁在调用main
)。您是否正在编写使用 C 运行时的应用程序?玛雅插件?Windows 服务?一个司机?每个案例都需要研究,看看是否exit
等同于return
. 恕我直言,exit
当您真正的意思 return
时使用只会使代码更加混乱。OTOH,如果你真的是意思 exit
,那么一定要使用它。
至少有一个理由更喜欢exit
:如果您的任何处理atexit
程序在未定义的行为,但调用是有效的。main
setvbuf
setbuf
main
main
exit
另一个潜在用途(通常保留给玩具程序)是从具有递归调用的程序中退出main
.
我总是使用return
,因为标准原型main()
说它确实返回一个int
.
也就是说,某些版本的标准给予main
特殊处理,并假设如果没有明确的return
声明它返回 0。给定以下代码:
int foo() {}
int main(int argc, char *argv[]) {}
G++ 仅生成警告foo()
并忽略来自 的缺失返回main
:
% g++ -Wall -c foo.cc
foo.cc: In function ‘int foo()’:
foo.cc:1: warning: control reaches end of non-void function
我强烈支持 R. 关于使用 exit() 的评论,以避免在main()
程序实际结束之前回收自动存储。in的return X;
语句main()
并不完全等同于对 的调用exit(X);
,因为动态存储在返回main()
时会消失main()
,但如果改为调用,它不会消失exit()
。
此外,在 C 或任何类似 C 的语言中,一条return
语句强烈暗示读者将在调用函数中继续执行,虽然如果计算调用main()
函数的 C 启动例程,这种继续执行通常在技术上是正确的,但事实并非如此当您打算结束该过程时,这正是您的意思。
毕竟,如果你想从任何其他函数中结束你的程序,除了main()
你必须调用exit()
. 始终如一地这样做main()
也会使您的代码更具可读性,并且还使任何人都可以更轻松地重构您的代码;main()
即,从其他函数复制的代码不会因为本应调用的意外return
语句而行为不端。exit()
因此,将所有这些点结合在一起,得出的结论是,至少对于 C 来说,使用语句结束程序是一个坏习惯。return
main()
exit() 会做任何“return”没有做的特殊事情吗?
对于不常见平台的一些编译器,exit()
可能会将其参数转换为程序的退出值,而 return frommain()
可能只是将值直接传递给主机环境而无需任何转换。
在这些情况下,该标准需要相同的行为(具体来说,它表示返回与int
- 兼容的内容main()
应该等同于exit()
使用该值进行调用)。问题是不同的操作系统有不同的解释退出值的约定。在许多(很多!)系统上,0 意味着成功,其他任何东西都是失败。但是在 VMS 上,奇数表示成功,偶数表示失败。如果您从 中返回 0 main()
,则 VMS 用户会看到一条关于访问冲突的令人讨厌的消息。实际上并没有访问冲突——这只是与失败代码 0 相关的标准消息。
然后 ANSI 出现并得到祝福EXIT_SUCCESS
,并且EXIT_FAILURE
可以作为参数传递给exit()
. 该标准还说exit(0)
应该与 的行为相同exit(EXIT_SUCCESS)
,因此大多数实现都定义EXIT_SUCCESS
为0
。
因此,该标准将您置于 VMS 的约束中,因为它没有留下任何标准方法来返回恰好具有值 0的故障代码。
因此,1990 年代早期的 VAX/VMS C 编译器没有解释 from 的返回值main()
,它只是将任何值返回给主机环境。但是,如果您使用exit()
它,它将执行标准要求的操作:将EXIT_SUCCESS
(或0
)转换为成功代码和EXIT_FAILURE
通用失败代码。要使用EXIT_SUCCESS
,你必须把它传递给exit()
,你不能从它返回main()
。我不知道该编译器的更现代版本是否保留了这种行为。
一个可移植的 C 程序曾经看起来像这样:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, World!\n");
exit(EXIT_SUCCESS); /* to get good return value to OS */
/*NOTREACHED*/ /* to silence lint warning */
return 0; /* to silence compiler warning */
}
另外:如果我没记错的话,退出值的 VMS 约定比奇数/偶数更细微。它实际上使用像低三位这样的东西来编码严重性级别。然而,一般来说,奇数严重级别表示成功或杂项信息,偶数严重级别表示错误。
在 C 中,从返回与使用相同的值main
调用exit
完全相同。
C 标准的第 5.1.2.2.3 节规定:
如果 main 函数的返回类型是与 int 兼容的类型,则从初始调用到 main 函数的 return 等效于以 main 函数返回的值作为参数调用 exit 函数;11)到达终止main函数的}返回值0。如果返回类型与int不兼容,则返回给宿主环境的终止状态是未指定的。
正如其他答案中提到的,C++ 的规则有点不同。
当你的函数被多次调用时exit(0)
,实际上是有区别return(0)
的。main
main
以下程序
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
return(0);
printf("%d", main(argc - 1, argv));
}
运行方式
./program 0 0 0 0
将产生以下输出:
00000
然而这个:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
exit(0);
printf("%d", main(argc - 1, argv));
}
无论参数如何,都不会打印任何内容。
如果您确定没有人会main
明确地调用您,那么从技术上讲,这通常不会有很大的不同,但是保持更清晰的代码exit
看起来会更好。如果您出于某种原因想要打电话main
- 您应该根据自己的需要进行调整。
谈到C。