返回语句与退出()在main()

我应该使用exit()还是仅在main() return语句? 就我个人而言,我喜欢return语句,因为我感觉它就像阅读任何其他函数一样,当我阅读代码时,stream程控制是平滑的(在我看来)。 即使我想重构main()函数, return似乎是比exit()更好的select。

exit()做了什么特别的return不?

其实有一个区别,但是很微妙。 它对C ++有更多的含义,但是区别很重要。

当我在main()调用return ,析构函数会被我的本地作用域对象调用。 如果我调用exit()将不会为我的本地作用域对象调用析构函数! 重新阅读。 exit() 不返回 。 这意味着一旦我称之为“没有后卫”。 您在该函数中创build的任何对象都不会被销毁。 通常这没有任何影响,但有时候它确实如closures文件(当然,你希望所有的数据都被刷新到磁盘上)。

请注意,即使调用exit()也会清除static对象。 最后要注意的是,如果使用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); } 

另外,这增加了一个额外的假设:从main调用exit有和返回零相同的副作用。 正如其他人已经指出的,这取决于你正在build立什么样的可执行文件(即谁打电话给main )。 你正在编写一个使用C运行时的应用程序吗? 玛雅插件? Windows服务? 一个司机? 每个案件将需要研究,看看exit是否相当于return 。 恕我直言,使用exit时,你真的意味着 return只是使代码更混乱。 OTOH,如果你真的意味着 exit ,那么一定要用它。

至less有一个理由更喜欢exit :如果你的任何一个atexit处理程序在main引用了自动存储持续时间数据,或者你使用了setvbufsetbuf来为其中一个标准stream分配一个自动存储持续时间缓冲区main ,然后从main返回产生未定义的行为,但是调用exit是有效的。

然而,另一个潜在的用法(通常是为玩具程序保留)是通过recursion调用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 

为了避免在程序实际结束之前回收main()中的自动存储,我强烈地使用了exit()的第二条注释。 return X; main()语句并不完全等同于exit(X);的调用exit(X); ,因为main()的dynamic存储在main()返回时消失了,但是如果调用exit()话,它不会消失。

此外,在C语言或任何类C语言中, return语句强烈暗示读者执行将继续执行在调用函数中,而如果您计算C调用main()的C启动例程,function,这不完全是你的意思是结束这个过程。

毕竟,如果你想从main()以外的任何其他函数中结束你的程序,你必须调用exit() 。 在main()一直这样做,使得你的代码更具可读性,而且任何人都可以更容易地重新分解你的代码。 即从main()复制到其他函数的代码将不会因为意外的return语句而导致错误,这些语句应该exit()调用。

所以,把所有这些点结合在一起的结论是,至less对于C来说,使用return语句来结束main()的程序是一个坏习惯

exit()做了什么特别的“返回”不?

使用一些编译器为非常见的平台, exit()可能会将其参数转换为程序的退出值,而从main()返回的值可能只是直接将值传递给主机环境而不进行任何翻译。

标准要求在这些情况下具有相同的行为(具体来说,它表示返回与main() int兼容的东西应该相当于使用该值调用exit() )。 问题是不同的操作系统有不同的约定来解释退出值。 在许多(很多!)系统中,0意味着成功,其他任何事情都是失败的。 但是,就VMS而言,奇数值意味着成功,甚至意味着失败。 如果您从main()返回0,则VMS用户将看到有关访问冲突的令人讨厌的消息。 实际上没有访问冲突 – 这只是与失败代码0关联的标准消息。

然后ANSI来了,祝福EXIT_SUCCESSEXIT_FAILURE作为你可以传递给exit() 。 该标准还指出exit(0)应该与exit(EXIT_SUCCESS)行为相同,所以大多数实现都将EXIT_SUCCESS定义为0

因此,这个标准把你放在VMS上,因为它没有标准的方法来返回碰巧值为0的失败代码。

20世纪90年代早期的时代,VAX / VMS C编译器并没有解释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公约的退出值比奇数/偶数更细微。 它实际上使用低三位来编码严重级别。 然而,一般来说,单数的严重程度表示成功或其他信息,偶数表示错误。