c++ return语句vs main()中的exit()

zphenhs4  于 2023-10-20  发布在  其他
关注(0)|答案(8)|浏览(133)

main()中使用exit()或仅使用return语句之间有区别吗?
就我个人而言,我更喜欢return语句,因为我觉得它就像阅读任何其他函数一样,而且当我阅读代码时,流控制是流畅的(在我看来)。即使我想重构main()函数,使用return似乎比exit()更好。
exit()能做return不能做的事情吗?

wlzqhblo

wlzqhblo1#

事实上,这是有区别的,但很微妙。它对C++有更多的影响,但差异很重要。
当我在main()中调用return时,将为我的局部作用域对象调用析构函数。如果我调用exit(),**不会为我的局部作用域对象调用析构函数!”重读它。exit()不返回。这意味着,一旦我调用它,就没有“回退”,在该函数中创建的任何对象都不会被销毁。这通常没有什么影响,但有时会有影响,比如关闭文件(您肯定希望所有数据都刷新到磁盘?).
请注意,即使您调用exit()static对象也会被清理。最后请注意,如果使用abort(),则不会销毁任何对象。也就是说,没有全局对象,没有静态对象,也没有局部对象会被调用它们的析构函数。

在选择退出而非返回时,请谨慎操作。

http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a

8ftvxx2r

8ftvxx2r2#

另一个区别:exit是一个标准库函数,因此您需要包含标头并链接到标准库。为了说明(在C++中),这是一个有效的程序:

int main() { return 0; }

但是要使用exit,你需要一个include:

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

这就增加了一个额外的假设:从main调用exit具有与返回零相同的副作用。正如其他人所指出的,这取决于您正在构建哪种可执行文件(即,谁在调用main)。您是否正在编写一个使用C运行时的应用程序?Maya插件?Windows服务?驱动程序?每个案例都需要研究exit是否等效于return。IMHO使用exit时,你 * 真正的意思是 * return只会使代码更加混乱。OTOH,如果你真的是指exit,那就用它吧。

kmynzznz

kmynzznz3#

至少有一个理由让我们更喜欢exit:如果您的任何atexit处理程序引用main中的自动存储持续时间数据,或者如果您使用setvbufsetbufmain中的自动存储持续时间缓冲区分配给一个标准流,则从main返回将产生未定义的行为,但调用exit是有效的。
另一种可能的用法(通常只用于玩具程序)是通过递归调用main退出程序。

13z8s7eq

13z8s7eq4#

我总是使用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
2ul0zpep

2ul0zpep5#

强烈第二次评论R。关于使用exit()以避免在程序实际结束之前回收main()中的自动存储。main()中的return X;语句并不完全等同于对exit(X);的调用,因为main()的动态存储在main()返回时消失,但如果调用exit(),它不会消失。
此外,在C或任何类似C的语言中,return语句强烈地暗示读者执行将在调用函数中继续,虽然这种执行的继续在技术上通常是正确的,如果你把调用main()函数的C启动例程计算在内,当你打算结束这个过程时,它并不完全是你的意思。
毕竟,如果你想在除了main()之外的任何其他函数中结束你的程序,你 * 必须 * 调用exit()。在main()中这样做也会使代码更具可读性,而且任何人都可以更容易地重构代码;也就是说,从main()复制到其他函数的代码不会因为意外的return语句而发生错误,这些语句应该是exit()调用。
所以,把所有这些点结合在一起的结论是,使用return语句以main()结束程序是一个坏习惯,至少对C来说是这样。

dddzy1tm

dddzy1tm6#

exit()有什么特殊功能是'return'没有的吗?
对于一些不常见平台的编译器,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的 failure 代码的标准方法。
因此,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对退出值的约定比奇/偶更微妙。它实际上使用类似低三位的东西来编码严重性级别。然而,一般来说,奇数严重性级别表示成功或杂项信息,偶数严重性级别表示错误。

anhgbhbe

anhgbhbe7#

在C中,从main返回与用相同的值调用exit完全相同。
C standard的第5.1.2.2.3节规定:
如果main函数的返回类型是与int兼容的类型,则main函数初始调用的返回等价于以main函数返回的值为参数调用exit函数; 11)到达终止main函数的}返回值0。如果返回类型与int不兼容,则返回到宿主环境的终止状态是未指定的。
C++的规则与其他答案中提到的有点不同。

yb3bgrhw

yb3bgrhw8#

main中,exit(0)return(0)实际上是有区别的-当你的main函数被多次调用时。
下面的程序

#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

将导致以下输出:

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。

相关问题