专栏首页C++核心准则原文翻译C++核心准则E.30:不要使用抛异常声明

C++核心准则E.30:不要使用抛异常声明

E.30: Don't use exception specifications

E.20:不要使用抛异常声明

Reason(原因)

Exception specifications make error handling brittle, impose a run-time cost, and have been removed from the C++ standard.

抛异常声明让错误处理更脆弱,强制产生运行时成本,已经从C++标准中被移除了。

Example(示例)

int use(int arg)
    throw(X, Y)
{
    // ...
    auto x = f(arg);
    // ...
}

If f() throws an exception different from X and Y the unexpected handler is invoked, which by default terminates. That's OK, but say that we have checked that this cannot happen and f is changed to throw a new exception Z, we now have a crash on our hands unless we change use() (and re-test everything). The snag is that f() may be in a library we do not control and the new exception is not anything that use() can do anything about or is in any way interested in. We can change use() to pass Z through, but now use()'s callers probably needs to be modified. This quickly becomes unmanageable. Alternatively, we can add a try-catch to use() to map Z into an acceptable exception. This too, quickly becomes unmanageable. Note that changes to the set of exceptions often happens at the lowest level of a system (e.g., because of changes to a network library or some middleware), so changes "bubble up" through long call chains. In a large code base, this could mean that nobody could update to a new version of a library until the last user was modified. If use() is part of a library, it may not be possible to update it because a change could affect unknown clients.

如果f()抛出了不同于X和Y的异常,就会激活意外的错误处理,而这个处理的默认动作就是终止程序。那样还好,假设我们已经检查过了,这种事情不会发生,这时如果f被修改为抛出一个新异常Z,系统马上就会发生崩溃,除非我们修改use()(并且重新进行完整测试)。麻烦在于f()可能处于某个我们无法控制的功能库中,而且对于新异常use()也没有什么可做的,或者根本就不感兴趣。我可以修改use()将Z传出,但是接下来user()的调用者可能需要跟着修改。情况很快就会失控。或者我们可以为use()增加try-catch结构将Z映射到一个可以接受的异常。情况很快会再次失控。注意成组修改异常经常发生在系统的底层(例如由于网络库或某个中间件发生变化),因此变更会像气泡一样向上传递至整个调用链。在大规模代码中,这可能意味着没有人可以将库更新到新版本,直到最后的调用者发生变更。如果use()是库的一部分,它可能无法更新,因为这种变更不知道会影响谁。

The policy of letting exceptions propagate until they reach a function that potentially can handle it has proven itself over the years.

让异常传播直至一个有可能处理它的函数,这样的原则已经证明自己很多年了。

Note(注意)

No. This would not be any better had exception specifications been statically enforced. For example, see Stroustrup94.

没有。坚持推进使用抛异常声明一点好处也没有。参见

Stroustrup. The Design and Evolution of C++ (Addison-Wesley, 1994).

Note(注意)

If no exception may be thrown, use noexcept or its equivalent throw().

如果不会抛出任何异常,使用noexcept或者和它等价的throw()

Enforcement(实施建议)

Flag every exception specification.

标记所有的抛出异常声明。

原文链接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#e30-dont-use-exception-specifications

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++核心准则ES.21: 不要在不需要时引入变量(或常量)

    Readability. To limit the scope in which the variable can be used.

    面向对象思考
  • C++核心准则DS.22:没有合适的初始值就不要定义变量

    Readability. Limit the scope in which a variable can be used. Don't risk used-be...

    面向对象思考
  • C++核心准则编译边学-F.20 输出结果时更应该使用返回值而不是输出参数

    A return value is self-documenting, whereas a & could be either in-out or out-on...

    面向对象思考
  • Android Studio 最新debug工具及与老版本工具对应关系

    原文链接:https://developer.android.com/studio/profile/monitor

    望天
  • 【Rust每周一库】csv - 文件读写库

    示范如何从stdin读取CSV数据并且将数据映射到定制结构体。结构体中的成员名称会默认与CSV数据中的表头相对应。

    MikeLoveRust
  • 这12件事让我很讨厌Hadoop

    文章作者Andrew C. Oliver是一位专业的软件顾问,同时还是北卡罗来纳州达勒姆大数据咨询公司Open Software Integrators的总裁和...

    CSDN技术头条
  • (五十五)c#Winform自定义控件-管道

    GitHub:https://github.com/kwwwvagaa/NetWinformControl

    冰封一夏
  • WebView 和 JS 交互,如何将 Java 对象和 List 传值给 JS ?

    随着混合开发模式比较流行,很多时候,我们需要在原生的基础上,使用 WebView 加载网页,这样控制更加方便。今天我们来看看,如何将 Java 对象 和 Lis...

    非著名程序员
  • 盘点Hadoop让人讨厌的12件事

    ? 1. Pig vs. Hive 你在 Pig 里用不了 Hive UDFS。在 Pig 中你必须用 HCatalog 来访问 Hive 表。你在 Hive...

    小莹莹
  • 凹坑缺陷检测

    threeQing

扫码关注云+社区

领取腾讯云代金券