gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 15:36:59 25 4
gpt4 key购买 nike

我在使用 C++ 代码时遇到过问题,调用者出乎意料地抛出了异常。阅读您正在使用的模块的每一行以查看它是否抛出异常以及如果是,是什么类型的异常并不总是可能或不切实际。

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

我想到了以下几点:

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

    • 优点:简单。
    • 缺点:受用户错误影响。
  2. 为了安全起见,我们可以在应用程序范围内使用 try/catch(...)

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

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

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

最佳答案

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

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

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

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

我通常会做 (1) 的变体:对于每个函数文档,它提供什么异常保证 - nothrow、strong、weak 或 none。最后一个是bug。第一个很珍贵但很少见,只有交换函数和析构函数才严格需要良好的编码。是的,它会出现用户错误,但任何带有异常的 C++ 编码方式都会出现用户错误。然后最重要的是,如果它有助于您执行 (1),还执行 (2) 和/或 (3)。

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

关于c++ - 是否有一个普遍接受的习惯用法来指示 C++ 代码可以抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1261558/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com