The initialiser for a constexpr
variable must be a constant expression (C++11 §7.1.5/9):
A
constexpr
specifier used in an object declaration declares the object asconst
. Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, [...]. Otherwise, or if aconstexpr
specifier is used in a reference declaration, every full-expression that appears in its initializer shall be a constant expression.
Note the following requirements for a constant expression (§5.19/2):
A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression, but subexpressions of [...] conditional operations that are not evaluated are not considered
[...]
an invocation of a
constexpr
function with arguments that, when substituted by function invocation substitution (7.1.5), do not produce a constant expression;[...]
a throw-expression (15.1).
Function invocation substitution for a constexpr
function is defined as follows (§7.1.5/5):
Function invocation substitution for a call of a
constexpr
function [...] means implicitly converting each argument to the corresponding parameter type as if by copy-initialization, substituting that converted expression for each use of the corresponding parameter in the function-body, and [...] implicitly converting the resulting returned expression or braced-init-list to the return type of the function as if by copy-initialization. Such substitution does not change the meaning.
As we saw above (§5.19/2), subexpressions of conditional operations that are not evaluated are not considered. f(42)
is not a constant expression because when you perform function invocation substitution on f
, it results in an expression with a throw
expression on the side of the conditional operation that is evaluated. On the other hand, for f(41)
, the throw
ends up on the side that isn't evaluated.
So the program is ill-formed. It doesn't matter whether the initialiser is actually reached or not because the program shouldn't compile.