Is the following C++14/C++1y program ill-formed according to the current draft?
#include <cstddef>
template<typename T, size_t n>
struct literal_array
{
T data[n];
};
template<typename T, size_t n, size_t m>
constexpr literal_array<T, n+m> operator+(literal_array<T, n> a,
literal_array<T, m> b)
{
literal_array<T, n+m> x;
for (size_t i = 0; i < n; i++)
x.data[i] = a.data[i];
for (size_t i = 0; i < m; i++)
x.data[n+i] = b.data[i];
return x;
}
int main()
{
constexpr literal_array<int, 3> a = { 1, 2, 3 };
constexpr literal_array<int, 2> b = { 4, 5 };
constexpr auto c = a + b;
}
Clang trunk (at time of writing) gives:
error: constexpr variable 'c' must be initialized by a constant expression
constexpr auto c = a + b;
^ ~~~~~
assignment to object outside its lifetime is not allowed in a constant expression
x.data[i] = a.data[i];
^
in call to 'operator+({{1, 2, 3}}, {{4, 5}})'
constexpr auto c = a + b;
^
What does it mean "assignment to object outside its lifetime"? The lifetime of x and its subobjects encloses the function, so what is it on about?
The program is ill-formed because you are not initializing
x
, if you change the definition to:clang
no longer complains and it compiles without error. Another solution would be to create constexpr consrtuctors.We can find this in the draft standard section
7.1.5
The constexpr specifier paragraph 3 which says:and includes the following bullet:
which contains this bullet (emphasis mine):
and later on we have the following example:
The complaint about the lifetime of
x
does not seem founded in the draft standard. The correct reason as far as I can tell should be something along the lines ofobject is not initialized
.The relevant quote from the draft standard on object lifetime would be section
3.8
Object lifetime paragraph 1 which says:Just in case I was missing something I also checked using std::is_trivial:
and the result as expected in
true
,.Update
I filed a bug report for this and the reply includes this statement: