【问题标题】:Are dynamic exception specifications invalid in c++17?c++17中的动态异常规范是否无效?
【发布时间】:2018-05-23 10:50:59
【问题描述】:

c++17 中的动态异常规范是否无效?像这样

void f() throw(int);

【问题讨论】:

标签: c++ exception c++17


【解决方案1】:

通用C++ guidelines discourages to use of exception specifications 与任何版本的 C++ 和新标准都已删除此功能。

E.30:不要使用异常规范

原因

异常规范使错误处理变得脆弱,强加一个 运行时成本,并且已从 C++ 标准中删除

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

如果f() 抛出与XY 不同的异常,则发生意外 处理程序被调用,默认情况下终止。没关系,但是说 我们已经检查过这不会发生并且f 更改为 抛出一个新异常Z,除非我们 更改use()(并重新测试所有内容)。问题是f() 可能是 在我们无法控制的库中,新的异常不是什么 use() 可以做任何事情或以任何方式感兴趣。我们 可以更改use() 以通过Z,但现在use() 的调用者 可能需要修改。这很快变得无法控制。 或者,我们可以将try-catch 添加到use() 以将Z 映射到 可接受的例外。这也很快变得难以管理。笔记 对异常集的更改通常发生在最低 系统级别(例如,由于网络库的更改或 一些中间件),因此通过长调用链更改“冒泡”。在 一个庞大的代码库,这可能意味着没有人可以更新到新的 库的版本,直到最后一个用户被修改。如果use() 是 库的一部分,可能无法更新它,因为 更改可能会影响未知客户。

让异常传播直到它们到达函数的策略 多年来,它已经证明了自己的潜力。

笔记

没有。如果有异常规范,这不会更好 静态强制执行。例如,请参阅Stroustrup94

笔记

如果不会抛出异常,请使用 noexcept 或等效的throw()

【讨论】:

  • Bjarne 和我都看到了动态异常提出的问题。他在电话中告诉我,某个他没有透露姓名的“大玩家”拒绝支持新标准,除非他们被包括在内。
  • @JiveDadson 这很有趣。似乎连标准委员会都不能免于游说。
  • 这是使用所谓的Exception-free 设计模式(例如Qt 框架使用它)的另一个原因,这意味着:1.源代码中任何位置的单个 trycatchthrow2. 没有任何关于任何错误的日志,因为没有。 3. 只有invalid-pointer 崩溃(这可能是由out of memory 或使用null 作为指针引起的)。 注意我在上面提到的是invalid-pointer crash而不是invalid-pointer exception,因为在C++中这总是会导致崩溃(我们只能附加到Unhandled Exception并转储它)
【解决方案2】:

它们在 C++17 中正式无效。但是,将 C++/语言/C++ 语言标准设置为 ISO C++17 的 Visual C++17 仍然允许它们。将警告级别设置为 3 或更高 [properties/General/Warning Level/] 会发出警告,

警告 C4290:C++ 异常规范被忽略,除非表明函数不是 __declspec(nothrow)

注意 throw() 仍然合法,相当于新添加的 noexcept。

【讨论】:

  • 我猜,但可能是 throw() 已被弃用,因此不应该被推荐,可能是没有链接的“故事”的故事。也许甚至可以解释为什么他们从一开始就是一个坏主意,或者只是一个链接到他们回答这个问题的网站上无数答案之一。 :)
  • 没有投反对票,但为什么 Visual C++ 17 仍然“允许”它是一个问题?首先,它显然不能强迫其用户更改所有使用异常规范的遗留代码。其次,使用/W4,您会收到一条显示warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow) 的诊断消息。你还需要什么?
  • @Tommy 我正在删除关于“故事”的部分,这是我在考虑该功能时与一位非常重要的人的电话交谈中了解到的。我正在研究 /W4 的东西。
  • @TommyAndersen:ISO C++ 不区分错误和警告。只要有诊断消息,就达到了一致性。然后由程序员决定代码是否应该一致。这完全没问题。当然,C++17 的特性存在问题,编译器未实现或未正确实现,但未能报告异常规范的诊断消息并不是其中之一。
  • @Tommy - StackOverflow 是一个难缠的听众。我试着帮忙,我的努力得到了一个覆盆子。那好吧。我已经编辑了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 2021-02-09
  • 1970-01-01
相关资源
最近更新 更多