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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:29:01  来源:igfitidea点击:

return statement vs exit() in main()

c++ccoding-stylereturnexit

提问by Srikanth

Should I use exit()or just returnstatements in main()? Personally I favor the returnstatements 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 returnseems like a better choice than exit().

我应该在 中使用exit()还是只使用return语句main()?就我个人而言,我更喜欢这些return语句,因为我觉得这就像阅读任何其他函数一样,而且当我阅读代码时,流程控制很流畅(在我看来)。即使我想重构main()函数,拥有return似乎比exit().

Does exit()do anything special that returndoesn'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 returnin 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?).

当我调用returnin 时main(),将为我的本地范围对象调用析构函数。如果我调用exit(),则不会为我的本地范围对象调用析构函数!重读那个。exit()不回。这意味着一旦我调用它,就“没有backsies”。您在该函数中创建的任何对象都不会被销毁。通常这没有任何影响,但有时确实如此,例如关闭文件(您肯定希望将所有数据刷新到磁盘?)。

Note that staticobjects 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: exitis 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 exityou'll need an include:

但要使用exit你需要一个包含:

#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }

Plus this adds an additional assumption: that calling exitfrom mainhas 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 exitis equivalent to return. IMHO using exitwhen you really meanreturnjust makes the code more confusing. OTOH, if you really do meanexit, then by all means use it.

此外,这增加了一个额外的假设:调用exitfrommain与返回零具有相同的副作用。正如其他人指出的那样,这取决于您正在构建的可执行文件类型(即,谁在调用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 atexithandlers refer to automatic-storage-duration data in main, or if you used setvbufor setbufto assign to one of the standard streams an automatic-storage-duration buffer in main, then returning from mainproduces undefined behavior, but calling exitis valid.

至少有一个更喜欢的原因exit:如果您的任何atexit处理程序引用 中的自动存储持续时间数据main,或者如果您使用setvbufsetbuf将 中的一个自动存储持续时间缓冲区分配给标准流之一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 returnstatement 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 returnstatements 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 returnstatement 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_SUCCESSand EXIT_FAILUREas 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_SUCCESSto 0.

然后 ANSI 出现并祝福EXIT_SUCCESSEXIT_FAILURE作为参数传递给exit(). 该标准还说exit(0)应该表现得与 相同exit(EXIT_SUCCESS),因此大多数实现都定义EXIT_SUCCESS0

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_FAILUREinto 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 returnbecause the standard prototype for main()says that it does return an int.

我总是使用,return因为标准原型 formain()说它确实返回一个int.

That said, some versions of the standards give mainspecial treatment and assume that it returns 0 if there's no explicit returnstatement. 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 mainis exactly the same as calling exitwith 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 mainfunction is called multiple times.

当您的函数被多次调用时,实际上exit(0)return(0)in之间存在差异。mainmain

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 mainexplicitly it is not technically a big difference in general, but to maintain clearer code exitwould 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。