2

下面是一些代码,其中编译器部分检测到方法声明(即使用“noexcept”说明符)和方法实现之间的不匹配。

编译器报告方法“bazExcept()”的警告,但没有报告“baz()”的任何内容。但是,我期待在这两种情况下都会发出警告,因为“bazSub()”可能会引发异常,并且“baz()”明确声明不会引发异常。

这是一项正在进行的工作(即以后的编译器版本将捕获这种情况)还是我对“noexcept”用法的误解?

// Tested with C++11 & C++17
// Tested with msvc 19, gcc 9 & clang 9
// Tested using https://godbolt.org/

// Specifier 'noexcept(false)' (same as no specifier) i.e. may throw exceptions.
void bar() noexcept(false) {}

// No specifier 'noexcept' means 'noexcept(false)' i.e. may throw exceptions.
void bazSub() { throw 42; }

// Specifier 'noexcept' means 'noexcept(true)' i.e. do not throw exceptions.
// Note: Compilers do not detect the problem i.e. bazSub may throw exception.
void baz() noexcept { bazSub(); }

// Specifier 'noexcept' means 'noexcept(true)' i.e. must not throw exceptions.
// Note: Compilers generate a warning.
void bazExcept() noexcept { throw 42; }

int main() {return 1;}

谢谢你的帮助。

4

1 回答 1

0

Why compilers fail to detect a 'noexcept' usage mismatch?

Because they are not required to. Compilers act according to the standard.

C++ draft in except#spec-5:

Whenever an exception is thrown and the search for a handler encounters the outermost block of a function with a non-throwing exception specification, the function std​::​terminate is called.

Followed by important note:

An implementation is not permitted to reject an expression merely because, when executed, it throws or might throw an exception from a function with a non-throwing exception specification.

Compilers are not permitted to reject throwing from noexcept function and throwing in a noexcept function just calls std::terminate.

于 2020-03-05T15:38:30.570 回答