【问题标题】:Why does "dynamic exception" guarantee cause overhead?为什么“动态异常”保证会导致开销?
【发布时间】:2013-07-29 03:48:03
【问题描述】:

在 C++11 中已弃用:

void foo() throw();

替换为

void foo() noexcept;

this article 中解释了这样做的原因(其中归结为同一件事)是因为

C++ 异常规范是在运行时而不是在编译时检查的,因此它们不提供程序员保证所有异常都已处理。

虽然这对我来说确实有意义,但我不明白为什么首先动态检查 throw(),或者为什么 noexcept 除了调用 std::terminate 而不是正常的堆栈展开之外不提供异常保证(这并不是 IMO 的可靠保证)。

难道不能在编译期间检查是否抛出异常,如果发生这种情况,编译会失败吗?在我看来,基本上有三种情况:

void foo() noexcept
{
    // 1. Trivial case
    throw myexcept();

    // 2. Try-catch case
    //    Necessary to check whether myexcept is derived
    //    from exception
    try 
    { 
        throw myexcept(); 
    } 
    catch(exception const & e)
    {}

    // 3. Nested function call
    //    Recursion necessary
    bar();
}

在 C++ 中为每种类型都实例化模板后,编译应用程序无论如何都要花很长时间 - 那么为什么不更改 noexcept 以强制编译器检查是否在编译期间抛出异常?

我看到的唯一困难是函数可能会或可能不会抛出取决于运行时状态 - 但在我看来,无论如何不应允许该函数自称noexcept

我是否遗漏了什么,或者是为了不进一步增加编译时间,还是为了让编译器开发人员轻松一些?

【问题讨论】:

  • 编译器无法知道您在函数中调用的库函数是否会引发异常。
  • throw() 是编译器向您提供的保证。 noexcept 是您对编译器的保证。
  • @PetrBudnik:当然有,任何未标记为noexcept 的函数都可能是throw
  • @MatthieuM。甚至不进入动态加载,您是否建议 C++11 编译器应该拒绝编译 void foo() noexcept( true ) { bar(); },其中 bar() 来自在引入 noexcept 关键字之前创建的库?
  • @KerrekSB:您的意思是编译器通过调用 terminate() 向您提供beat you senseless 的保证,如果仍然抛出异常(并且通过不展开堆栈来违反所有 RAII 期望)?跨度>

标签: c++ c++11 throw noexcept


【解决方案1】:

我认为这在很大程度上归结于这样一个事实,即在定义异常规范时,编译器编写者远远落后于功率曲线。实现 C++98 非常复杂,以至于只有 一个 编译器甚至 声称 可以实现其所有功能。每个其他编译器都至少遗漏了标准中包含的一个主要功能。大多数人相当公开地承认,他们遗漏的内容远不止这些。

您还需要记住,动态异常规范也比throw() 复杂得多。它允许程序员指定一组可以抛出的任意类型。更糟糕的是,指定一个函数可以抛出 foo 意味着它也可以抛出从 foo 派生的任何东西。

本来可以静态地强制执行异常规范,但显然会增加相当多的额外工作,而且没有人真正确定它会带来什么(如果有的话)好处。在这种情况下,我认为大多数人很容易认为静态强制是以后可能需要的东西,如果似乎有足够的用途来证明这项工作的合理性。从运行时强制更改为编译时不需要修改现有代码,只需修改现有实现即可。

另一点是,我不确定是否真的强烈支持异常规范。我认为在基本想法上达成了普遍共识,但当你深入了解它时,可能就不那么关心细节了。

底线:很容易只强制执行动态执行,而将静态执行留到以后(如果有的话)。事实证明,在任何情况下,静态强制执行可能都不会真正增加那么多积极因素,因此强制执行可能无论如何也不会取得太大成就。

【讨论】:

    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 2012-10-29
    相关资源
    最近更新 更多