的措辞[expr.unary.noexcept]改变于C++17.
之前 (n4140, 5.3.7 noexcept 运算符 [expr.unary.noexcept] https://timsong-cpp.github.io/cppwp/n4140/expr.unary.noexcept), 我的重点:
- The result of the noexcept operator is false if in a potentially-evaluated context the expression would contain
(3.1) 对函数、成员函数的潜在评估调用,
函数指针,或没有成员函数指针
非抛出异常规范([except.spec]),除非打电话
是一个常量表达式 ([expr.const]) ...
Now1 (7.6.2.6 noexcept operator [expr.unary.noexcept] https://eel.is/c++draft/expr.unary.noexcept):
- noexcept 运算符的结果是true除非表达式可能抛出异常([ except.spec] )。
然后在14.5 异常规范[ except.spec ] https://eel.is/c++draft/except.spec:
- 如果函数的声明没有 noexcept 说明符,则该声明具有可能引发异常的说明,除非...
but the 除非列出14.5(3) 未列出constexpr
,将其保留为可能抛出...
1 a link to C++17 n4659 https://timsong-cpp.github.io/cppwp/n4659/except.spec#6 added by L.F. in a comment.
测试代码
constexpr int f(int i) { return i; }
std::cout << boolalpha << noexcept(f(7)) << std::endl;
int a = 7;
std::cout << boolalpha << noexcept(f(a)) << std::endl;
用于打印(与海湾合作委员会8.3 https://godbolt.org/z/ivAnRa):
true
false
两者都在编译时使用-std=c++11 and -std=c++2a
However现在打印相同的代码(与海湾合作委员会9.2 https://godbolt.org/z/GWUEdg):
false
false
两者都在编译时使用-std=c++11 and -std=c++2a
顺便说一句,Clang 非常一致,从3.4.1开始 https://godbolt.org/z/UsBDok并与:
false
false
- 每个规范的正确行为是什么?
- 规格有真正的变化吗?如果是这样,这种变化的原因是什么?
- 如果规范中的更改影响或与过去的行为相矛盾,那么常见的做法是强调这种变化及其影响?如果改变是没有强调这是否意味着它可能是监督?
- 如果这是真正有意的更改,是否认为它是一个错误修复,应该追溯到规范的先前版本,编译器是否正确地将新行为追溯至 C++11?
Side Note: the noexcept
deduction on a constexpr
function affects this trick https://stackoverflow.com/a/35110453/2085626.