10

I have the code:

struct A {
    int a;
};

struct B {
    int b;
    const A a[2];
};

struct C {
    int c;
    const B b[2];
};

const C test = {0, {}};

int main()
{
    return test.c;
}

I have gcc 4.8.2 and 4.9.2. It can be compiled just fine with:

g++-4.9 -Wall test.cpp -o test
g++-4.8 -std=c++11 -Wall test.cpp -o test
g++-4.8 -Wall test.cpp -o test

However, it can't be compiled with:

g++-4.9 -std=c++11 -Wall test.cpp -o test

And the compiler output is:

test.cpp:15:22: error: uninitialized const member ‘B::a’
 const C test = {0, {}};
                      ^
test.cpp:15:22: error: uninitialized const member ‘B::a’

Is this a bug or I just don't understand something?

Nikita Karpinsky
  • 503
  • 4
  • 10

1 Answers1

3

This is a bug that essentially reduces to GCC complaining about not-explicitly-initialized const data members in aggregate initialization. E.g.

struct {const int i;} bar = {};

Fails as there is no initializer-clause for i in bar's initializer. However, the standard specifies in §8.5.1/7 that

If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal-initializer, from an empty initializer list (8.5.4).

Thus the code initializes i (as if by = {}), and GCCs complaint is incorrect.

In fact, this bug has already been reported four years ago as #49132, and is fixed in GCC 5.

James Greenhalgh
  • 2,401
  • 18
  • 17
Columbo
  • 60,038
  • 8
  • 155
  • 203