在C++中,exit和std::exit之间有什么区别

what is the difference between exit and std::exit in C++?

本文关键字:exit 之间 什么 区别 C++ std      更新时间:2023-10-16

C++中的exitstd::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++中,std::exit/exit(无论如何获得其名称)确实有一些C库中未为exit指定的行为。特别是

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

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

这意味着,实际上,您应该真正忘记以上所有内容,并简单地永远不要从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);。这样,所有的局部变量都将被销毁(即,堆栈展开将发生),然后您将正常退出环境。

exit(当使用C++编译器时)是通过标头stdlib.h从C标准库"借用"的。

std::exit是C++标准库版本;在CCD_ 23中定义。

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

当您之前声明:using namespace std;时,std::exitexit 之间没有区别

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

因此,您也可以编写cout而不是std::cout

没有真正的区别。除非在不同的作用域/名称空间中有不同的函数exit(如果有,那么我不知道该说什么——就是不要说),否则exit()::exit()std::exit()是一样的。

不过,您通常不希望调用exit,因为这样做会在不运行本地和全局析构函数(仅atexit注册函数)的情况下终止程序有时(很少)这是你想要的,但通常不是——你想从main返回。