clang 3.4
does not compile this code since sum(get_str())
is not a constexpr and as far as I can tell clang
is correct here, this line (see it live):
constexpr int s = sum(get_str());
generates the following error:
error: constexpr variable 's' must be initialized by a constant expression
constexpr int s = sum(get_str());
^ ~~~~~~~~~~~~~~
note: read of temporary whose lifetime has ended
return str[0] + str[1] + str[2] + str[3]
^
It is not a valid constexpr
for two reasons. This invokes undefined behavior and this is explicitly disallowed in a constant expression, to summarize the draft C++ standard section 5.19
says:
A conditional-expression e is a core constant expression unless the evaluation of e,
and contains the following bullet:
an operation that would have undefined behavior
which accessing outside of its lifetime would be. We know the lifetime of the temporary is not extended in this case from section 12.2
Temporary objects which says:
The second context is when a reference is bound to a temporary.117 The
temporary to which the reference is bound or the temporary that is the
complete object of a subobject to which the reference is bound
persists for the lifetime of the reference except
and includes the following bullet:
The lifetime of a temporary bound to the returned value in a function
return statement (6.6.3) is not extended; the temporary is destroyed
at the end of the full-expression in the return statement.
So although it is indeed true that a constant expression is not guaranteed to be evaluated at translation, we have a note in section 5.19
Constant expressions that mentions this (emphasis mine going forward):
Note: Constant expressions can be evaluated during translation.—end
note ]
Even if it was guaranteed we still would not be allowed to invoke undefined behavior.
The second issue is that constexpr references must be either to objects of static storage duration or functions, cppreference mentions this in its core constant expression section:
Reference constant expression is an lvalue core constant expression
that designates an object with static storage duration or a function
and as far as I can tell this is covered in section 5.19
Constant expressions paragraph 4 which says:
each non-static data member of reference type refers to an object with
static storage duration or to a function,