Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to member-initialize a non-static array member in a constexpr class?

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?

like image 982
IceFire Avatar asked May 24 '16 12:05

IceFire


2 Answers

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).

like image 140
StoryTeller - Unslander Monica Avatar answered Oct 04 '22 01:10

StoryTeller - Unslander Monica


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);
...

like image 29
Serge Ballesta Avatar answered Oct 04 '22 01:10

Serge Ballesta