是否有一个普遍接受的习惯用法来指示 C++ 代码可以抛出异常?

2023-11-26

我在使用 C++ 代码时遇到过问题,调用者意外地抛出异常。读取您正在使用的模块的每一行来查看它是否抛出异常以及如果抛出异常,则并不总是可行或不切实际的。

是否存在处理此问题的既定惯用语或“最佳实践”?

我想到了以下几点:

  1. 在我们的 doxygen 文档中,我们可以在每个预期抛出异常的函数及其类型中添加注释。

    • 优点:简单。
    • 缺点:容易出现用户错误。
  2. 我们可以有一个应用程序范围try/catch(...)为了安全。

    • 优点:我们不会再有任何未捕获的异常。
    • 缺点:异常是在距离抛出很远的地方捕获的。很难弄清楚该做什么或出了什么问题。
  3. 使用异常规范

    • 优点:这是处理这个问题的语言认可的方法。
    • 缺点:需要重构问题库才能有效。在编译时不强制执行,因此违规会变成运行时问题,这正是我试图避免的!

这些方法有什么经验,或者我不知道的任何其他方法?


标题问题的简短回答 - 表示函数可以抛出的惯用语是not记录它“这个函数不会抛出”。也就是说,默认情况下一切都可以抛出。

C++ 不是 Java,并且没有编译器检查的异常。 C++ 中没有任何东西可以让编译器告诉你你的代码声称它不会抛出,但调用了可能会抛出的东西。所以你不能完全避免这是一个运行时问题。静态分析工具可能会有所帮助,但不确定。

如果您只关心 MSVC,您可以考虑使用空异常规范或__declspec(nothrow)在不抛出异常的函数上,以及throw(...)在功能上。这不会导致代码效率低下,因为 MSVC 不会发出代码来检查声明为 nothrow 的函数实际上不会抛出。 GCC 也可以做同样的事情-fno-enforce-eh-specs,检查你的编译器文档。然后一切都将被自动记录。

选项 2,应用程序范围的 try-catch 并不是真正的“为了安全”,这只是因为你认为你可以用异常做一些更有用的事情(比如打印出一些东西并干净地退出),而不仅仅是让 C++ 运行时调用terminate。如果您在编写代码时假设某件事不会抛出,而实际上确实发生了,那么您可能在其中任何一个实际发生之前就已经未定义,例如,如果析构函数对一致状态做出了错误的假设。

我通常会做(1)的变体:对于每个函数记录它提供的异常保证 - 不抛出、强、弱或无。最后一个是一个错误。第一个很有价值但很少见,并且只有交换函数和析构函数才严格需要良好的编码。是的,它可能会出现用户错误,但任何带有异常的 C++ 编码方式都会出现用户错误。然后,如果它可以帮助您执行(1),那么还可以执行(2)和/或(3)。

Symbian 有一个预标准的 C++ 方言,有一个称为“leave”的机制,在某些方面类似于异常。 Symbian 中的约定是任何可能离开的函数都必须以 L 结尾命名:CreateL, ConnectL平均而言,这会减少用户错误,因为您可以更轻松地看到您是否正在调用可能会离开的内容。正如您所料,讨厌它的人就像讨厌应用程序匈牙利表示法一样,如果几乎所有功能都离开它,它就不再有用。正如您所期望的,如果您确实编写了一个名称中没有 L 的函数,那么在您找出问题之前,它可能会在调试器中等待很长时间,因为您的假设使您远离了实际的错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有一个普遍接受的习惯用法来指示 C++ 代码可以抛出异常? 的相关文章

随机推荐

  • 用 C/C++ 编写的语法突出显示库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我正在寻找一个免费的 用于商业用途 库 用于用 c c 编写的语法着色 那里有吗 我不确定您是否正在寻找为现有控件或内置文本着色的控件着色的东西 如果您正在寻找后者 您可以查看 Sc
  • Winforms - 如何更改 ListView 控件中行的颜色?

    使用 C Winforms 3 5 是否可以将行颜色设置为在列表视图中自动交替 或者每次将新行添加到列表视图时是否需要手动设置行颜色 基于一个MSDN文章手动方法如下所示 alternate row color if i 2 0 lvi B
  • 如何在“宽高比”模式下将 UIImageView 裁剪为新的 UIImage?

    我想通过裁剪 UIImageView 内的图像来创建一个新的 UIImage 例如 在上图中 我想要一个绿色轮廓区域的新 UIImage 我找到了执行此操作的代码 通常它看起来像这样 作为 UIImage 类别 UIImage croppe
  • 智能 gwt 教程和指导 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我是 smart gwt 的新手 我需要一些帮助 请帮助提供一些好的 smart gwt 教程以及一些我可以购买来学习这一点的好书 我做了一些搜索
  • 当网络完全收敛时停止 Keras 训练

    如何配置 Keras 停止训练直到收敛或损失为 0 时 我故意想要过度拟合它 我不想设置纪元数 我只是想让它在收敛时停止 Use an 提前停车打回来 您可以自由选择要观察的损失 指标以及何时停止 通常 您会查看 验证损失 val loss
  • 清空关系数据库架构

    我有一个已备份的数据库 现在我试图删除原始数据库中的所有内容并将其恢复到空状态 因为它是一个关系数据库 所以它有关键的约束 我可以使用任何工具吗 最简单的方法可能是禁用外键检查 然后截断表 由于外键已禁用 因此截断表的顺序并不重要 set
  • App Engine:传输密码并将其安全存储在 Google App Engine 中的最佳做法是什么?

    我想知道从网络表单传输密码并将其存储在数据存储中的最先进技术是什么 最近的很多帖子都指出bcrypt但是 没有纯 Python 实现 而这是 App Engine 的要求 有什么建议么 最佳实践 将 Users API 与 Google 帐
  • 恢复 .orig 文件的简单方法?

    我刚走一不小心就跑了hg revert Mercurial 是否附带一个工具来移动所有 orig文件放回原处 不 如果你在 bash 中 你可以随时执行以下操作 for thefile in orig do cp v thefile the
  • 在 WordPress 中集成 Bootstrap 轮播,无需插件

    我已将 bootstrap carousel 集成到我的 WordPress 中 幻灯片将从标记为 精选 的帖子中获取 因此只会显示 5 个最近输入的 精选 帖子 下面是我的代码 div class carousel slide bs do
  • 如何将之前的路线作为 Angular 中的路径?

    如何将之前的路线作为 Angular 中的路径 我尝试使用解决方案这个链接 但它不会在首页加载时执行 constructor router Router router events pipe filter event gt event in
  • 记忆栅栏 - 需要帮助才能理解

    我正在读 Paul E McKenney 的 记忆障碍 http www rdrop com users paulmck scalability paper whymb 2010 07 23a pdf一切都解释得很详细 当我看到一切都清楚的
  • Javascript正则表达式在每第三个和第四个字符后添加破折号

    以下正则表达式 x toString replace B d 3 d g 在每个后面添加破折号3rd如此输入的字符123456789变成123 456 789 我正在尝试使用此正则表达式来格式化电话号码 问题出现在第 10 个字符上 于是进
  • SVM 的标准化特征值

    我一直在尝试一些 SVM 实现 我想知道 标准化特征值以适应一个范围的最佳方法是什么 从0到1 假设我有 3 个特征 其值范围为 3 5 0 02 0 05 10 15 如何将所有这些值转换为 0 1 范围 如果在训练期间 我将遇到的特征号
  • Rails 5 模型对象未显示所有 Devise 属性

    我正在使用 Rails 5 API 和设备 我有一个User模型 架构看起来像这样 create table users force cascade do t t string email default null false t stri
  • 将鼠标悬停在 Chrome 字段建议上会缩小输入

    我正在使用最新版本的 Chrome 74 0 3729 169 并注意到一些有点令人沮丧 有趣的事情 在下面的示例中 开始输入您之前使用过的电子邮件地址 Chrome 的建议出现后 将鼠标悬停在其中一项建议上 请注意输入的缩减程度如何 in
  • 从 Objective-C 类调用 C++ 构造函数

    如何从 Objective C 类内部调用 C 构造函数 class CppClass public CppClass int arg1 const std string arg2 arg1 arg1 arg2 arg2 private i
  • Postgresql - 如何使用正则表达式模式提取字符串中第一次出现的子字符串?

    我正在尝试使用正则表达式从文本列中提取子字符串 但在某些情况下 字符串中存在该子字符串的多个实例 在这些情况下 我发现查询不会返回子字符串的第一次出现 有谁知道我做错了什么 例如 如果我有这个数据 create table data1 fu
  • 如何按列剪辑 pandas 数据框?

    I have In 67 a Out 67 0 1 2 0 1 2 3 1 4 5 6 当我跑步时 In 69 a clip lower 1 5 2 5 3 5 axis 1 I got ValueError other must be t
  • @NotNull 注释未按预期工作 Java Jersey

    我有一个端点实现 我将一个对象传递给参数列表 我试图使用 NotNull 注释来验证该对象不为空 POST Path path public Response endpointMethod NotNull ApiParam value ab
  • 是否有一个普遍接受的习惯用法来指示 C++ 代码可以抛出异常?

    我在使用 C 代码时遇到过问题 调用者意外地抛出异常 读取您正在使用的模块的每一行来查看它是否抛出异常以及如果抛出异常 则并不总是可行或不切实际的 是否存在处理此问题的既定惯用语或 最佳实践 我想到了以下几点 在我们的 doxygen 文档