我应该使用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
你需要一个包括:
#includeint main() { exit(EXIT_SUCCESS); }
另外,这增加了一个额外的假设:调用exit
来自main
返回零具有相同的副作用.正如其他人所指出的,这取决于你正在构建什么样的可执行文件(即谁在调用main
).您在编写使用C运行时的应用程序吗?Maya插件?一个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()
在程序实际结束之前回收自动存储。return X;
in中的语句main()
并不完全等同于对的调用exit(X);
,因为返回main()
时动态存储消失了main()
,但是如果exit()
改为调用,它就不会消失。
此外,在C或任何类似C的语言中,一条return
语句强烈地向读者暗示执行将在调用函数中继续,并且从技术上讲,这种连续执行通常是正确的,如果您算上调用了main()
函数的C启动例程,则不是到底是什么,你的意思是,当你的意思是结束该进程。
毕竟,如果你想从任何其它函数中结束你的程序,除了main()
你必须调用exit()
。一致地执行此操作main()
还可以使您的代码更具可读性,并且任何人都可以更轻松地重构您的代码。即从复制的代码main()
,因为偶然的一些其他功能不会胡作非为return
,发言应被exit()
调用。
因此,将所有这些点结合在一起,得出的结论是,至少对于C语言来说,使用语句在中结束程序是一种不良习惯。return
main()
exit()会执行“返回”没有的特殊功能吗?
对于某些不常见平台的编译器,exit()
可能会将其参数转换为程序的退出值,而从的返回main()
可能只是将值直接传递给主机环境,而无需任何转换。
在这些情况下,该标准要求具有相同的行为(特别是,它说返回与- int
兼容的内容main()
应该等同于exit()
使用该值进行调用)。问题在于,不同的操作系统具有不同的解释出口值的约定。在许多(MANY!)系统上,0表示成功,其他则表示失败。但是在VMS上,奇数表示成功,偶数表示失败。如果从返回0 main()
,则VMS用户将看到有关访问冲突的令人讨厌的消息。实际上并没有访问冲突-仅仅是与故障代码0相关的标准消息。
然后ANSI出现并得到祝福EXIT_SUCCESS
,EXIT_FAILURE
作为参数可以传递给ANSI exit()
。该标准还说exit(0)
应该表现得与之相同exit(EXIT_SUCCESS)
,因此大多数实现都将其定义EXIT_SUCCESS
为0
。
因此,该标准使您陷入VMS的困境,因为它没有标准的方法可以返回恰好具有值0 的失败代码。
因此,1990年代初期的VAX / VMS C编译器没有解释的返回值main()
,它只是将任何值返回给主机环境。但是,如果使用exit()
它,它将满足标准要求:将EXIT_SUCCESS
(或0
)转换为成功代码和EXIT_FAILURE
通用失败代码。要使用它EXIT_SUCCESS
,您必须将其传递给exit()
,您不能从中将其返回main()
。我不知道该编译器的更现代版本是否保留了该行为。
一个可移植的C程序,看起来像这样:
#include#include 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约定比奇/偶更细微。实际上,它使用诸如低三位之类的代码来对严重性级别进行编码。但是,一般而言,奇数严重性级别表示成功或其他信息,偶数严重性级别表示错误。