TLDR
The program is ill-formed and the respective compilers are wrong in accepting the code because the int prvalue expression 5
is not a contextually converted constant expression of type bool
which(if supplied) is required to be a contextually converted constant expression by the noexcept-specifier
. Basically, the reason for the program being ill-formed is the same for why bool b{5};
is ill-formed as well i.e., this involves a narrowing conversion.
From exception specification documentation:
1) The exception specification is either defined implicitly,
or defined explicitly by using a noexcept-specifier as a suffix of a function declarator
noexcept-specifier:
noexcept ( constant-expression )
noexcept
throw ( )
2) In a noexcept-specifier, the constant-expression, if supplied, shall be a contextually converted constant expression of type bool; that constant expression is the exception specification of the function type in which the noexcept-specifier appears.
(emphasis mine)
This means that for the program to be well-formed the supplied constant expression(which is 5
in our example) needs to be a contextually converted constant expression of type bool.
Now lets see from expr.const#4 whether 5
is a contextually converted constant expression or not:
4.10) A contextually converted constant expression of type bool is an expression, contextually converted to bool, where the converted expression is a constant expression and the conversion sequence contains only the conversions above.
4.7) integral conversions other than narrowing conversions,
And from narrowing conversion
A narrowing conversion is an implicit conversion
- from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
(emphasis mine)
This means that the conversion from int prvalue 5
to bool true
is a narrowing conversion and so 5
is not a contextually converted constant expression of type bool and so the program is ill-formed and the respective compilers are wrong in accepting the code.
Basically, the reason for the program being ill-formed is that same as to why bool b{3};
is ill-formed. You can even see the you'll get the same error. Demo
Here is the msvc bug report:
MSVC accepts invalid narrowing conversion
Here is the clang bug report:
Clang accepts invalid narrowing conversion