C++ 中的 exit 和 std::exit 有什么区别?

问题描述 投票:0回答:5

C++ 中的

exit
std::exit
有什么区别?我研究过,但没有找到任何东西。

这两个代码有什么区别:

1:

if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
    std::cout << "Error: Can't initialize the SDL \n";
    exit(EXIT_FAILURE);
}

2:

if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
    std::cout << "Error: Can't initialize the SDL \n";
    std::exit(EXIT_FAILURE);
}
c++ exit
5个回答
16
投票

它们是执行相同操作的同一函数的两个名称。

但请注意,在 C++ 中,

std::exit
/
exit
(无论您如何获得其名称)确实具有一些 C 库中未为
exit
指定的行为。特别是,

  1. exit
    首先销毁与当前线程关联的所有具有线程存储持续时间的对象。
  2. 具有静态存储持续时间的对象将被销毁,并调用任何使用
    atexit
    注册的函数。
    • 如果其中一个抛出未捕获的异常,则调用
      terminate
  3. 之后我们得到正常的 C 行为:
    • 如果打开的 C 流有未写入的数据,则会刷新它们,然后将其关闭。
    • 通过调用
      tmpfile
      创建的文件将被删除。
    • 控制返回到主机环境,返回成功或失败,具体取决于调用
      exit
      时传递的值(
      0
      EXIT_SUCCESS
      => 成功,
      EXIT_FAILURE
      => 失败,其他任何内容均由实现定义) .

特别注意,本地对象不会被任何退出调用破坏。

这意味着,实际上,您应该真正忘记上述所有内容,并且简单地never从C++代码中调用

exit
/
std::exit
。虽然委员会显然认为与 C 代码的兼容性是一个足够强大的动机,他们“需要”将其保留在标准中,但您当然不需要使用它 - 并且在几乎任何合理的正常情况下,您不应该使用它。在退出作用域时销毁本地对象是 C++ 中非常重要的一部分,以至于像 exit 这样消除这种保证的函数几乎只会带来头痛。

如果您需要与

exit

大致相似的行为,您通常会想要执行以下操作:


struct my_exit : public std::exception { int value; my_exit(int value) : value(value) {} }; int main() { try { // do normal stuff } catch(my_exit const &e) { return e.value; } }

然后在代码的其余部分中,否则您会调用 
exit

,而改为

throw my_exit(whatever_value);
。这样,所有局部变量都将被销毁(即,将发生堆栈展开),然后
然后
您将正常退出环境。


9
投票
exit

(使用 C++ 编译器时)通过标头

stdlib.h
从 C 标准库“借用”。

std::exit

是C++标准库版本;定义于

cstdlib

在 C++ 中你应该使用后者,但这两个函数做的事情完全相同。


1
投票
exit

的函数(如果你这样做了;好吧,我不知道该说什么 - 只是不这样做),

exit()
::exit()
std::exit()
是同样的事情。

您通常不

想要

调用exit,因为这样做会终止程序而不运行本地和全局析构函数(仅

atexit
注册函数)。
有时
(很少)这就是您想要的,但通常不是 - 您想从 main 返回。
    


0
投票
using namespace std;

std::exit
exit
 之间没有区别

此声明允许避免写入前缀 std。

所以你也可以写

cout

而不是

std::cout
    


0
投票

这是

/usr/include/c++/11/cstdlib

中 Linux Ubuntu 22.04 上的一个。

正如我们所见,

std::exit()

函数(以及其他一些函数)只是对普通 C

exit()
的简单引用。在那里,真的是0差异。
namespace std
{
  extern "C" void abort(void) throw () _GLIBCXX_NORETURN;
  extern "C" int atexit(void (*)(void)) throw ();
  extern "C" void exit(int) throw () _GLIBCXX_NORETURN;
#if __cplusplus >= 201103L
# ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT
  extern "C" int at_quick_exit(void (*)(void)) throw ();
# endif
# ifdef _GLIBCXX_HAVE_QUICK_EXIT
  extern "C" void quick_exit(int) throw() _GLIBCXX_NORETURN;
# endif
#endif
} // namespace std

	
© www.soinside.com 2019 - 2024. All rights reserved.