jeudi 3 janvier 2019

Why is a member not getting zero-initialized in this example?

This is specifically regarding C++11:

#include <iostream>
struct A {
    A(){}
    int i;
};
struct B : public A {
    int j;
};
int main() {
    B b = {};
    std::cout << b.i << b.j << std::endl;
}

Compiling with g++ 8.2.1:

$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
a.cpp: In function ‘int main()’:
a.cpp:25:25: warning: ‘b.B::<anonymous>.A::i’ is used uninitialized in this function [-Wuninitialized]
     std::cout << b.i << " " << b.j << std::endl

gcc is detecting b.i as uninitialized, but I would think it should be getting zero-initialized along with b.j.

From cppreference (C++11 specifically):

  • B is not an aggregate because it has a base class. Public base classes were only allowed in aggregates in C++17.
  • A is not an aggregate because it has a user-provided constructor
  • b is getting list initialized with an empty braced-init-list
  • "If the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed."
    • B has an implicitly-defined default constructor.
  • Now during value-initialization: "if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized"
    • So b gets zero-initialized
  • Now during zero-initialization: "If T is an non-union class type, all base classes and non-static data members are zero-initialized, and all padding is initialized to zero bits. The constructors, if any, are ignored."
    • So it's recursive. b.B::A gets zero-initialized, which zero-initalizes b.B::A.i, and then b.B::j gets zero-initialized.

However, it looks like gcc is saying only b.B::j is going to get zero-initialized. Why is this? The only reason I can think of is if B is being treated as an aggregate, which would initialize b.B::A with an empty list. However B should not be an aggregate in this case, correct?

Aucun commentaire:

Enregistrer un commentaire