7

The following code desperately needs : values() to compile, at least in ideone::C++14:

#include <iostream>

template<int N>
struct Table
{
    constexpr Table() : values()
    {
        for (auto i = 0; i < N; ++i)
        {
            values[i] = i * i * i;
        }
    }
    int values[N];
};

int main() {
    constexpr auto a = Table<1000>();
    for (auto x : a.values)
        std::cout << x << '\n';
}

But why? I had thoughts along "values could also be initialized in a non-constexpr way and values() does explicitly say that we initialize it in a constexpr-compliant manner". But is not omitting : values() just as clear?

3
  • clang gives a strange message: assignment to object outside its lifetime is not allowed in a constant expression for the = in the constructor of Table if I omit values(). Commented May 24, 2016 at 12:45
  • "for the constructor of a class or struct, every base class sub-object and every non-variant non-static data member must be initialized. " Commented May 24, 2016 at 13:36
  • But it is initialized anyways, just Not explicit in any case. It works for non-constexpr classes Commented May 24, 2016 at 13:43

2 Answers 2

5

Consider the semantics.

Omitting the member from the initialization list will perform default initialization, which in this case leaves the array with unspecified values. That negates the purpose of a constexpr.

Value initializing the array performs zero initialization on each array element (since this is an array of built in types).

Sign up to request clarification or add additional context in comments.

3 Comments

this indeed makes sense and I did not know that
Still, why is it not allowed to initialize the elements in the for loop? Afterwards, all array elements have values
@JohannesSchaub-litb, For simplicity of implementation, I think. Judging by the quote Serge put bellow, the committee may have thought the following the c'tor chain may be less intractable than tracking an arbitrary c'tor body.
2

Simply because it is required by standard. Draft n4296 for current C++ standard states at :

7.1.5 The constexpr specifier [dcl.constexpr] §4 (emphasize mine):

4 The definition of a constexpr constructor shall satisfy the following constraints:
...

In addition, either its function-body shall be = delete, or it shall satisfy the following constraints:

(4.4) — either its function-body shall be = default, or the compound-statement of its function-body shall satisfy the constraints for a function-body of a constexpr function;
(4.5) — every non-variant non-static data member and base class sub-object shall be initialized (12.6.2);
...

1 Comment

Perhaps the standard should clarify really that default initialization does not apply as "initialized". However, having an unspecified value really should preclude from being a constexpr, so I guess it follows logically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.