终止,终止还是退出?

这三者之间的区别是什么,我应该如何结束程序的情况下,我不能正确处理异常?

65708 次浏览
  • 终止使您可以注册调用它时将发生的事情。应该是另外两个中的一个。
  • Exit 是允许指定退出状态的正常退出
  • 终止是一个异常退出。唯一运行的是 SIGABRT 的信号处理程序。

我的建议是不要使用其中任何一个。相反,在 main()中无法处理的异常是 catch,而在 return中只能处理这些异常。这意味着可以保证正确地进行堆栈展开并调用所有析构函数。换句话说:

int main() {
try {
// your stuff
}
catch( ... ) {
return 1;    // or whatever
}
}
  • Abort 表示程序的“异常”结束,并引发 POSIX 信号 SIGABRT,这意味着您为该信号注册的任何处理程序都将被调用,尽管在这两种情况下程序仍将在后面终止。通常,在 C 程序中使用 abort可以避免出现意外的错误情况,这种情况下错误很可能是程序中的 bug,而不是像错误输入或网络故障这样的情况。例如,如果发现一个数据结构中有一个 NULL 指针,而在逻辑上不应该发生这种情况,那么可以使用 abort

  • Exit 表示程序的“正常”结束,尽管这可能仍然表示失败(但不是 bug)。换句话说,如果用户提供的输入无法解析,或者文件无法读取,那么您可能会使用错误代码 exit。退出代码为0表示成功。exit还可以在结束程序之前调用处理程序。这些函数用 atexiton_exit函数注册。

  • 在 C + + 程序中,当出现未处理的异常时,会自动调用 std: : finally 。这实际上是与 abort等价的 C + + ,假设您通过抛出异常来报告所有异常错误。这将调用由 std::set_terminate函数设置的处理程序,该函数在默认情况下仅调用 abort

在 C + + 中,您通常希望避免在出现错误时调用 abortexit,因为最好抛出一个异常,并让调用堆栈上的代码决定是否应该结束程序。是否使用 exit获得成功是一个环境问题——在 main中的 return 语句之外的其他地方结束程序是否有意义。

即使在 C + + 中,std::terminate也应该被认为是最后的错误报告工具。std::terminate的问题在于终止处理程序确实能够访问未处理的异常,所以没有办法知道它是什么。通常最好将整个 main 包装在一个 try { } catch (std::exception& ex) { }块中。至少您可以报告关于从 std::exception派生的异常的更多信息(当然,不是从 std::exception派生的异常最终仍然是未处理的)。

try { } catch(...) { }中包装 main的主体并不比设置终止处理程序好多少,因为您同样无法访问所讨论的异常。但是,至少有一个好处: 当异常完全未捕获时,堆栈解除是否已完成,这是实现定义的,因此如果需要确保堆栈解除,这将是一种实现方法。

  • 会自动调用 finally () 当发生不能 默认情况下,终止() 调用 abort () 函数的句柄。

    Abort ()发送 SIGABRT 信号。

    Exit ()不一定是坏的 事件。它成功退出 应用程序和 exit ()调用 按照后进先出顺序运作,我没有 通常在 C + + 中看到这个 然而,我确实看到了它的应用 许多基于 Unix 的应用程序 最后发送一个退出代码。 通常出口(0)表示 应用程序运行成功

Abort 和 std: : Exit (以及更多: std: : _ Exit,std: : fast _ Exit)只是较低级别的函数。你用它们来告诉程序你想要它做什么: 调用什么析构函数(如果) ,调用什么其他的清理函数,返回什么值,等等。

Finally 是一个更高层次的抽象: 它被调用(由运行时或您)来指示程序中发生了错误,并且由于某种原因不可能通过抛出异常来处理。这样做的必要性通常发生在异常机制本身发生错误时,但是当您不希望程序在给定的错误之后继续运行时,可以随时使用它。当 std: : finally 被称为 在我的岗位上时,我编译了完整的情况列表。它没有指定 std: : finally 的作用,因为您可以控制它。您可以通过注册任何函数来配置行为。您所受到的限制是,函数不能返回到错误站点,也不能通过异常退出,但是从技术上讲,您甚至可以在内部启动消息泵。有关您可以在里面做的有用事情的列表,请参见 我的另一个职位

特别要注意的是,在 std: : finally 由于无法处理抛出的异常而被调用的上下文中,std: : finally 被认为是一个异常处理程序,您可以检查异常是什么,并使用 C + + 11使用 std: : rethrow _ Exception 和 std: : current _ Exception 检查异常。都在 我的岗位里。

Quick _ exit ()

如果您的程序是多线程的,那么调用 exit()很可能会导致崩溃,因为全局/静态 std::thread对象将尝试在不退出其线程的情况下进行销毁。

如果希望返回错误代码并正常退出程序(或多或少) ,请在多线程程序中调用 quick_exit()。 对于异常终止(无法指定错误代码) ,可以调用 abort()std::terminate()

注: MSVC + + 不支持 fast _ exit ()直到2015年版本。