C++ main() 中的 return 语句与 exit()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/461449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
return statement vs exit() in main()
提问by Srikanth
Should I use exit()
or just return
statements in main()
? Personally I favor the return
statements because I feel it's like reading any other function and the flow control when I'm reading the code is smooth (in my opinion). And even if I want to refactor the main()
function, having return
seems like a better choice than exit()
.
我应该在 中使用exit()
还是只使用return
语句main()
?就我个人而言,我更喜欢这些return
语句,因为我觉得这就像阅读任何其他函数一样,而且当我阅读代码时,流程控制很流畅(在我看来)。即使我想重构main()
函数,拥有return
似乎比exit()
.
Does exit()
do anything special that return
doesn't?
有没有exit()
做一些特别的事情return
?
回答by FreeMemory
Actually, there isa difference, but it's subtle. It has more implications for C++, but the differences are important.
其实是有区别的,但是很微妙。它对 C++ 有更多影响,但差异很重要。
When I call return
in main()
, destructors will be called for my locally scoped objects. If I call exit()
, no destructor will be called for my locally scoped objects!Re-read that. exit()
does not return. That means that once I call it, there are "no backsies." Any objects that you've created in that function will not be destroyed. Often this has no implications, but sometimes it does, like closing files (surely you want all your data flushed to disk?).
当我调用return
in 时main()
,将为我的本地范围对象调用析构函数。如果我调用exit()
,则不会为我的本地范围对象调用析构函数!重读那个。exit()
不回。这意味着一旦我调用它,就“没有backsies”。您在该函数中创建的任何对象都不会被销毁。通常这没有任何影响,但有时确实如此,例如关闭文件(您肯定希望将所有数据刷新到磁盘?)。
Note that static
objects will be cleaned up even if you call exit()
. Finally note, that if you use abort()
, no objects will be destroyed. That is, no global objects, no static objects and no local objects will have their destructors called.
请注意,static
即使您调用exit()
. 最后请注意,如果您使用abort()
,则不会销毁任何对象。也就是说,不会调用全局对象、静态对象和局部对象的析构函数。
Proceed with caution when favoring exit over return.
在倾向于退出而不是返回时要谨慎行事。
http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a
http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a
回答by jwfearn
Another difference:
exit
is a Standard Library
function so you need to include
headers and link with the standard
library. To illustrate (in C++),
this is a valid program:
另一个区别:
exit
是标准库函数,因此您需要包含标头并链接到标准库。为了说明(在 C++ 中),这是一个有效的程序:
int main() { return 0; }
but to use exit
you'll need an include:
但要使用exit
你需要一个包含:
#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }
Plus this adds an additional assumption: that calling exit
from main
has the same side effects as returning zero. As others have pointed out, this depends on what kind of executable you're building (i.e., who's calling main
). Are you coding an app that uses the C-runtime? A Maya plugin? A Windows service? A driver? Each case will require research to see if exit
is equivalent to return
. IMHO using exit
when you really meanreturn
just makes the code more confusing. OTOH, if you really do meanexit
, then by all means use it.
此外,这增加了一个额外的假设:调用exit
frommain
与返回零具有相同的副作用。正如其他人指出的那样,这取决于您正在构建的可执行文件类型(即,谁在调用main
)。您是否正在编写使用 C 运行时的应用程序?玛雅插件?Windows 服务?一个司机?每个案例都需要研究,看看是否exit
相当于return
。恕我直言,exit
在您真正的意思时使用return
只会使代码更加混乱。OTOH,如果你真的是故意的exit
,那么一定要使用它。
回答by R.. GitHub STOP HELPING ICE
There is at least one reason to prefer exit
: If any of your atexit
handlers refer to automatic-storage-duration data in main
, or if you used setvbuf
or setbuf
to assign to one of the standard streams an automatic-storage-duration buffer in main
, then returning from main
produces undefined behavior, but calling exit
is valid.
至少有一个更喜欢的原因exit
:如果您的任何atexit
处理程序引用 中的自动存储持续时间数据main
,或者如果您使用setvbuf
或setbuf
将 中的一个自动存储持续时间缓冲区分配给标准流之一main
,则从main
产生返回未定义的行为,但调用exit
是有效的。
Another potential usage (usually reserved for toy programs, however) is to exit from a program with recursive invocations of main
.
另一种潜在的用法(通常为玩具程序保留)是从递归调用main
.
回答by Greg A. Woods
I STRONGLYsecond the comment by R. about using exit() in order to avoid having automatic storage in main()
reclaimed before the program actually ends. A return X;
statement in main()
is not precisely equivalent to a call to exit(X);
, since the dynamic storage of main()
vanishes when main()
returns, but it it does not vanish if a call to exit()
is made instead.
我强烈支持R. 关于使用 exit() 的评论,以避免main()
在程序实际结束之前回收自动存储。一个return X;
在声明中main()
不完全等效于一个电话exit(X);
,因为动态存储main()
时消失main()
的回报,但如果调用它,它不会消失,exit()
由代替。
Furthermore, in C or any C-like language a return
statement strongly hints to the reader that execution will continue in the calling function, and while this continuation of execution is usually technically true if you count the C startup routine which called your main()
function, it's not exactly what youmean when you mean to end the process.
此外,在 C 或任何类似 C 的语言中,return
声明强烈地向读者暗示执行将在调用函数中继续,虽然如果计算调用main()
函数的 C 启动例程,这种继续执行在技术上通常是正确的,但它不是当您打算结束该过程时,这正是您的意思。
After all, if you want to end your program from within any other function except main()
you mustcall exit()
. Doing so consistently in main()
as well makes your code much more readable, and it also makes it much easier for anyone to re-factor your code; i.e. code copied from main()
to some other function won't misbehave because of accidental return
statements that shouldhave been exit()
calls.
毕竟,如果你想从任何其他函数中结束你的程序,除非main()
你必须调用exit()
. 始终如一地这样做main()
会使您的代码更具可读性,并且任何人都可以更轻松地重构您的代码;即从main()
其他函数复制的代码不会因为应该被调用的意外return
语句而行为不端。exit()
So, combining all of these points together the conclusion is that it's a bad habit, at least for C, to use a return
statement to end the program in main()
.
因此,结合所有这些问题的共同结论是,这是一个不好的习惯,至少在C,使用return
语句来结束该计划main()
。
回答by Adrian McCarthy
Does exit() do anything special that 'return' doesn't?
exit() 有什么特别的东西是'return' 没有的吗?
With some compilers for uncommon platforms, exit()
might translate its argument into your program's exit value while a return from main()
might just pass the value directly to the host environment without any translation.
对于不常见平台的一些编译器,exit()
可能会将其参数转换为程序的退出值,而返回值main()
可能只是将值直接传递给主机环境而无需任何转换。
The standard requires identical behavior in these cases (specifically, it says returning something that's int
-compatible from main()
should be equivalent to calling exit()
with that value). The problem is that different OSes have different conventions for interpreting the exit values. On many (MANY!) systems, 0 means success and anything else is a failure. But on, say, VMS, odd values mean success and even ones mean failure. If you returned 0 from main()
, a VMS user would see a nasty message about an access violation. There wasn't actually an access violation--that was simply the standard message associated with failure code 0.
在这些情况下,标准要求相同的行为(特别是,它说返回int
-compatible from 的东西main()
应该等同于exit()
使用该值调用)。问题是不同的操作系统有不同的解释退出值的约定。在许多(许多!)系统上,0 表示成功,其他任何内容都是失败。但是在 VMS 上,奇数意味着成功,偶数意味着失败。如果您从 返回 0 main()
,VMS 用户将看到有关访问冲突的令人讨厌的消息。实际上没有访问冲突——这只是与失败代码 0 相关联的标准消息。
Then ANSI came along and blessed EXIT_SUCCESS
and EXIT_FAILURE
as arguments you could pass to exit()
. The standard also says that exit(0)
should behave identically to exit(EXIT_SUCCESS)
, so most implementations define EXIT_SUCCESS
to 0
.
然后 ANSI 出现并祝福EXIT_SUCCESS
并EXIT_FAILURE
作为参数传递给exit()
. 该标准还说exit(0)
应该表现得与 相同exit(EXIT_SUCCESS)
,因此大多数实现都定义EXIT_SUCCESS
为0
。
The standard, therefore, puts you in a bind on VMS, as it leaves no standard way to return a failurecode that happens to have the value 0.
因此,该标准将您置于 VMS 的绑定中,因为它没有留下返回值恰好为 0的故障代码的标准方法。
The early-1990s era VAX/VMS C compiler therefore did not interpret the return value from main()
, it simply returned whatever value to the host environment. But if you used exit()
it would do what the standard required: translate EXIT_SUCCESS
(or 0
) into a success code and EXIT_FAILURE
into a generic failure code. To use EXIT_SUCCESS
, you hadto pass it to exit()
, you could not return it from main()
. I don't know whether more modern versions of that compiler preserved that behavior.
因此,1990 年代早期的 VAX/VMS C 编译器没有解释 的返回值main()
,它只是将任何值返回给主机环境。但是,如果您使用exit()
它,它将执行标准要求的操作:将EXIT_SUCCESS
(或0
) 转换为成功代码和EXIT_FAILURE
通用失败代码。要使用EXIT_SUCCESS
,您必须将其传递给exit()
,您无法从main()
. 我不知道该编译器的更现代版本是否保留了这种行为。
A portable C program used to look like this:
一个可移植的 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 */
}
Aside: If I recall correctly, the VMS convention for exit values is more nuanced than odd/even. It actually uses something like the low three bits to encode a severity level. Generally speaking, however, the odd severity levels indicated success or miscellaneous information and the even ones indicated errors.
旁白:如果我没记错的话,退出值的 VMS 约定比奇数/偶数更微妙。它实际上使用类似于低三位的东西来编码严重性级别。但是,一般来说,奇数严重级别表示成功或杂项信息,偶数严重级别表示错误。
回答by Alnitak
I always use return
because the standard prototype for main()
says that it does return an int
.
我总是使用,return
因为标准原型 formain()
说它确实返回一个int
.
That said, some versions of the standards give main
special treatment and assume that it returns 0 if there's no explicit return
statement. Given the following code:
也就是说,某些版本的标准给出了main
特殊处理,并假设如果没有明确的return
声明它会返回 0 。鉴于以下代码:
int foo() {}
int main(int argc, char *argv[]) {}
G++ only generates a warning for foo()
and ignores the missing return from main
:
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
回答by dbush
In C returning from main
is exactly the same as calling exit
with the same value.
在 C 中,从返回与使用相同的值main
调用exit
完全相同。
Section 5.1.2.2.3 of the C standardstates:
C 标准的第 5.1.2.2.3 节规定:
If the return type of the main function is a type compatible with int , a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; 11) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int , the termination status returned to the host environment is unspecified.
如果 main 函数的返回类型是与 int 兼容的类型,则从初始调用到 main 函数的返回等效于以 main 函数返回的值作为参数调用 exit 函数;11) 到达终止 main 函数的 } 返回值 0。如果返回类型与 int 不兼容,则返回到宿主环境的终止状态是未指定的。
The rules for C++ are a bit different as mentioned in other answers.
如其他答案中所述,C++ 的规则略有不同。
回答by radrow
There actually IS a difference between exit(0)
and return(0)
in main
–?when your main
function is called multiple times.
当您的函数被多次调用时,实际上exit(0)
和return(0)
in之间存在差异。main
main
The following program
下面的程序
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
return(0);
printf("%d", main(argc - 1, argv));
}
Run as
运行方式
./program 0 0 0 0
Will result in following output:
将导致以下输出:
00000
However this one:
然而这个:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
exit(0);
printf("%d", main(argc - 1, argv));
}
Won't print anything regardless of the arguments.
无论参数如何,都不会打印任何内容。
If you are sure that nobody will ever call your main
explicitly it is not technically a big difference in general, but to maintain clearer code exit
would look much better. If you for some reason want to call main
– you should adjust it to your needs.
如果您确定没有人会main
明确地调用您,那么从技术上讲,通常不会有太大的区别,但是保持更清晰的代码exit
看起来会好得多。如果您出于某种原因想要致电main
– 您应该根据自己的需要进行调整。
Speaking about C.
说到 C。