exit(0) 在 MFC 中会造成任何问题吗?

发布于 2024-10-19 04:43:26 字数 90 浏览 1 评论 0原文

我想立即退出 C++ 中的 MFC 应用程序。 exit(0) 是最好的解决方案吗?例如。它是否阻止析构函数被调用,它是线程安全的吗?等等,有更好的解决方案吗?谢谢。

I want to immediately exit my MFC app in C++. Is exit(0) the best solution? eg. does it prevent destructors from being called, is it threadsafe? etc. Is there a better solution? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

醉殇 2024-10-26 04:43:26

是的,exit(0) 是最好的解决方案。它将导致全局对象(以及函数内的静态对象)的析构函数运行,但不会导致堆栈分配或堆分配对象的析构函数运行:

// At global scope
ClassWithDestruct globalObject;

void SomeFunction()
{
    static ClassWithDestructor staticObject;
    ClassWithDestructor stackObject;
    ClassWithDestructor *heapObject = new ClassWithDestructor;

    // On the following call to exit(), the destructors of 'globalObject' and
    // 'staticObject' will run, but those of 'stackObject' and 'heapObject' will
    // NOT run
    exit(0);
}

至于它是否是线程-安全,这是一个很难回答的问题:您不应该从多个线程同时调用 exit,您应该只调用它一次。如果任何析构函数由于exit而运行,或者任何使用atexit 运行,那么显然,如果这些函数处理可能被其他线程使用的数据,那么它们应该是线程安全的。

如果您的程序正常退出(例如,由于用户请求退出),您应该调用 exit 或从 main/WinMain 返回code>,相当于调用exit。如果您的程序异常退出(例如,由于访问冲突或断言失败),您应该调用 _exitabort,其中调用任何析构函数。

Yes, exit(0) is the best solution. It will cause the destructors of global objects (and static objects within functions) to run, however it will not cause destructors of stack-allocated or heap-allocated objects to run:

// At global scope
ClassWithDestruct globalObject;

void SomeFunction()
{
    static ClassWithDestructor staticObject;
    ClassWithDestructor stackObject;
    ClassWithDestructor *heapObject = new ClassWithDestructor;

    // On the following call to exit(), the destructors of 'globalObject' and
    // 'staticObject' will run, but those of 'stackObject' and 'heapObject' will
    // NOT run
    exit(0);
}

As to whether or not it's thread-safe, that's a hard question to answer: you should not be calling exit simultaneously from multiple threads, you should only call it once. If any destructors run as a result of exit, or any if any functions registered with atexit run, then obviously those functions should be thread-safe if they deal with data that could potentially be being used by other threads.

If your program is exiting normally (say, as a result of the user requesting an exit), you should either call exit or return from main/WinMain, which is equivalent to calling exit. If your program is exiting abnormally (say, as a result of an access violation or failed assertion), you should call either _exit or abort, which do not call any destructors.

第七度阳光i 2024-10-26 04:43:26

如果您想立即退出,并确保事先不运行任何析构函数等,那么您可能需要调用abort()。如果您确实希望执行析构函数,那么您可能需要使用PostQuitMessage(0);。不管怎样,exit() 可能是错误的选择。

If you want to exit immediately, ensuring against running any destructors and such beforehand, then you probably want to call abort(). If you do want destructors to execute, then you probably want to use PostQuitMessage(0);. Either way, exit() is probably the wrong choice.

染火枫林 2024-10-26 04:43:26

当 win32 进程退出时,操作系统会清除与其关联的任何资源,所以对我来说这是完全可以的。

when a win32 process exits any resource associated with it is cleaned up by the OS, so in order to me it is perfectly ok.

梦在夏天 2024-10-26 04:43:26

exit(0) 退出进程。所有内存都被清理干净。另一方面,显式管理的资源可能不会被关闭。当然,文件句柄将被关闭,Windows 缓冲区中的内容将被刷新。但是应用程序管理的内容不会。

exit(0) exits the process. All memory is cleaned up. On the other hand explicitly managed resources may not be closed. Of course file handles would be closed and stuff in windows buffers will be flushed. However stuff that the application manages will not.

深海蓝天 2024-10-26 04:43:26

不,这不是结束程序的安全方法。静态存储数据和非本地自动对象将被破坏,但本地自动对象不会。

从 C++ 标准 18.3/8 开始:

函数exit()有额外的
在这个国际上的行为
标准:

  • 一、静态存储的对象
    持续时间和功能被破坏
    通过调用atexit注册
    叫。具有静态的非本地对象
    存储期限被破坏[...]。
    (自动对象不会被破坏
    作为调用的结果
    exit().)[207]) […] 本地静态
    对象 obj3 同时被销毁
    函数调用的时间
    obj3 析构函数已注册
    完成后使用 atexit
    obj3 构造函数。

  • 接下来,所有打开的 C 流(如
    由函数签名调解
    中声明,但未写入
    缓冲数据被刷新,所有打开的C
    流已关闭,所有文件
    通过调用 tmpfile() 创建的有
    已删除。[209])

[207]:自动存储的对象
持续时间全部被摧毁
其函数 main() 的程序
不包含自动对象并且
执行对 exit() 的调用。控制
可以直接转移到这样的
main() 通过抛出异常
main() 捕获。

[209]:与以下内容关联的任何 C 流
cincout 等 (27.3) 被刷新
并在静态对象存在时关闭
在前一阶段被摧毁。这
函数 tmpfile() 声明于


与此相关的是,std::exit(EXIT_SUCCESS) 具有令人不安的误导性。

No, it's not a safe way to end your program. Static-storage data and non-local automatic objects will destruct, but local automatic objects will not.

From 18.3/8 in the C++ standard:

The function exit() has additional
behavior in this International
Standard:

  • First, objects with static storage
    duration are destroyed and functions
    registered by calling atexit are
    called. Non-local objects with static
    storage duration are destroyed […].
    (Automatic objects are not destroyed
    as a result of calling
    exit().)[207]) […] A local static
    object obj3 is destroyed at the same
    time it would be if a function calling
    the obj3 destructor were registered
    with atexit at the completion of the
    obj3 constructor.

  • Next, all open C streams (as
    mediated by the function signatures
    declared in <cstdio>) with unwritten
    buffered data are flushed, all open C
    streams are closed, and all files
    created by calling tmpfile() are
    removed.[209])

[207]: Objects with automatic storage
duration are all destroyed in a
program whose function main()
contains no automatic objects and
executes the call to exit(). Control
can be transferred directly to such a
main() by throwing an exception that
is caught in main().

[209]: Any C streams associated with
cin, cout, etc (27.3) are flushed
and closed when static objects are
destroyed in the previous phase. The
function tmpfile() is declared in
<cstdio>.


On a related note, std::exit(EXIT_SUCCESS) is disturbingly misleading.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文