问题标签 [exception-specification]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
151 浏览

c++ - 是否允许编译器支持标准中删除的功能?

在第一段cppreference.com中明确指出throw(T1, ..., Tn)在 C++17 中已删除。

让我感到困惑的是,一些编译器支持throw(T1, ..., Tn)C++17 模式(参见演示)。

  • MSVC 默认支持它,但您可以为其打开警告,请参阅C5040。它可以变成一个错误/we5040
  • 默认情况下,Clang 将其报告为错误,但可以使用-Wno-dynamic-exception-spec.
  • GCC 让您别无选择:这是一个错误。

是否允许编译器支持标准中删除的功能?出于什么目的?

或者这只是一个编译器扩展,就像void foo(int size) { char a[size]; }在 GCC 中一样,请参阅demo

0 投票
1 回答
190 浏览

c++ - 什么是初始化的子表达式

考虑从except.spec#11引用的上述代码。我对 D 的所有构造函数的异常规范毫无疑问,除了D::D(D&&),它遵守以下规则:

为类 X 隐式声明的构造函数,或在其第一个声明中默认没有 noexcept 说明符的构造函数,当且仅当以下任何构造可能抛出异常时,才具有潜在抛出异常规范:

  • 在类 X 的构造函数的隐式定义中通过重载决议选择的构造函数来初始化可能构造的子对象,或
  • 这种初始化的子表达式,例如默认参数表达式,或者,
  • 对于默认构造函数,默认成员初始值设定项。

显然,D​::​D(D&&)具有潜在抛出异常规范的规则既不是第一个项目符号也不是第三个项目符号。对于第一条规则,用于初始化类型基子对象的选定构造函数BB(B&&, int = (throw Y(), 0)) noexcept,它被声明为具有非抛出异常规范。第三条规则适用于默认构造函数。所以只有第二条规则适用于这种情况。

但是,D​::​D(D&&)除了表达式throw Y()被视为D​::​D(D&&).

定义立即子表达式的规则如下:

表达式 e 的直接子表达式是

  1. e 的操作数的组成表达式
  2. e 隐式调用的任何函数调用
  3. 如果 e 是 lambda 表达式,则由 copy 捕获的实体的初始化以及 init-captures 的初始化程序的组成表达式,
  4. 如果 e 是函数调用或隐式调用函数,则调用中使用的每个默认参数的组成表达式,或
  5. 如果 e 创建了一个聚合对象,则初始化中使用的每个默认成员初始值设定项 ([class.mem]) 的组成表达式。

表达式 e 的子表达式是 e 的直接子表达式或 e 的直接子表达式的子表达式。

理解子表达式规则的简单方法是它递归地工作,也就是说,

immediate subexpression of immediate subexpression... of immediate subexpression of e是 的子表达式e

由于第四个项目符号,我同意该表达式throw Y()是函数的子表达式。B(B&&, int = (throw Y(), 0)) noexcept但是,我不知道是否B(B&&, int = (throw Y(), 0)) noexcept被视为由表达式调用的隐式调用函数D​::​D(D&&),这似乎服从第二个项目符号。如果是这样,请考虑以下代码:

所以,正如我在评论中所写,构造函数和析构函数Test是否被视为表达式的子表达式func()?如果不是,如何解释措辞a subexpression of such an initialization?所以,我的问题是:

Q1:

在第二个示例中,隐式调用的构造函数或析构函数是否被视为表达式的子表达式func()

Q2:

如果第一个问题的答案是否定的,那么如何解释a subexpression of such an initialization

0 投票
1 回答
65 浏览

c++ - 我怎么知道确切的异常类型?

我们使用CDynamicAccessorwhich 继承自CAccessorBase. 该函数MoveNext会抛出

HRESULT MoveNext() throw()

但没有告诉它是什么异常类型。我怎么知道?

0 投票
0 回答
629 浏览

c++ - 错误:ISO C++17 不允许动态异常规范

我正在尝试使用新的 GCC 版本 11.2.0 运行我的项目,并且遇到动态异常规范错误的问题:

mtree.h:669:85:错误:ISO C++17 不允许动态异常规范 669 | void addData(const Data& data, double distance, const mtree* mtree) throw(SplitNodeReplacement) { | ^~~~~

mtree.h:723:98:错误:ISO C++17 不允许动态异常规范 723 | virtual void doRemoveData(const Data& data, double distance, const mtree* mtree) throw (DataNotFound) = 0;

...

我不擅长 C++。所以,请帮我解决这个问题。我已经更改了默认配置设置(即“cppStandard”:“c++17”到“cppStandard”:“c++11”),但仍然遇到同样的问题。 错误描述截图

请参考项目代码的链接 - https://github.com/erdavila/M-Tree

相同的代码在 Windows 8.1 中运行,现在在我将其更新到 Windows 10 时遇到了这个问题。有没有办法修复它?