【发布时间】:2018-05-23 10:50:59
【问题描述】:
c++17 中的动态异常规范是否无效?像这样
void f() throw(int);
【问题讨论】:
-
不知道为什么这被否决了。这是一个非常合理的问题。 cmets 中的每个人基本上都在说 RTFM,这是非常粗鲁的。如果每个人都会粗鲁无礼,那么问答网站还有什么意义呢?
c++17 中的动态异常规范是否无效?像这样
void f() throw(int);
【问题讨论】:
通用C++ guidelines discourages to use of exception specifications 与任何版本的 C++ 和新标准都已删除此功能。
E.30:不要使用异常规范
原因异常规范使错误处理变得脆弱,强加一个 运行时成本,并且已从 C++ 标准中删除。
例子int use(int arg) throw(X, Y) { // ... auto x = f(arg); // ... }如果
f()抛出与X和Y不同的异常,则发生意外 处理程序被调用,默认情况下终止。没关系,但是说 我们已经检查过这不会发生并且f更改为 抛出一个新异常Z,除非我们 更改use()(并重新测试所有内容)。问题是f()可能是 在我们无法控制的库中,新的异常不是什么use()可以做任何事情或以任何方式感兴趣。我们 可以更改use()以通过Z,但现在use()的调用者 可能需要修改。这很快变得无法控制。 或者,我们可以将try-catch添加到use()以将Z映射到 可接受的例外。这也很快变得难以管理。笔记 对异常集的更改通常发生在最低 系统级别(例如,由于网络库的更改或 一些中间件),因此通过长调用链更改“冒泡”。在 一个庞大的代码库,这可能意味着没有人可以更新到新的 库的版本,直到最后一个用户被修改。如果use()是 库的一部分,可能无法更新它,因为 更改可能会影响未知客户。让异常传播直到它们到达函数的策略 多年来,它已经证明了自己的潜力。
笔记没有。如果有异常规范,这不会更好 静态强制执行。例如,请参阅Stroustrup94。
笔记如果不会抛出异常,请使用
noexcept或等效的throw()。
【讨论】:
Exception-free 设计模式(例如Qt 框架使用它)的另一个原因,这意味着:1.源代码中任何位置的单个 try、catch 或 throw。 2. 没有任何关于任何错误的日志,因为没有。 3. 只有invalid-pointer 崩溃(这可能是由out of memory 或使用null 作为指针引起的)。 注意我在上面提到的是invalid-pointer crash而不是invalid-pointer exception,因为在C++中这总是会导致崩溃(我们只能附加到Unhandled Exception并转储它)
它们在 C++17 中正式无效。但是,将 C++/语言/C++ 语言标准设置为 ISO C++17 的 Visual C++17 仍然允许它们。将警告级别设置为 3 或更高 [properties/General/Warning Level/] 会发出警告,
警告 C4290:C++ 异常规范被忽略,除非表明函数不是 __declspec(nothrow)
注意 throw() 仍然合法,相当于新添加的 noexcept。
【讨论】:
throw() 已被弃用,因此不应该被推荐,可能是没有链接的“故事”的故事。也许甚至可以解释为什么他们从一开始就是一个坏主意,或者只是一个链接到他们回答这个问题的网站上无数答案之一。 :)
/W4,您会收到一条显示warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow) 的诊断消息。你还需要什么?