Дефолтный конструктор не инициализирует константу

const struct A {
    // A() = default;
    int x;
} a;

int main() {}

Почему программа не компилируется? Как исправить?

uninitialized const 'a'


Ответы (3 шт):

Автор решения: Pak Uula

g++ в варианте C++17 на ваш код отреагировал вот как:

some.cpp:4:3: error: uninitialized const ‘a’ [-fpermissive]
 } a;
   ^
some.cpp:1:14: note: ‘const struct A’ has no user-provided default constructor
 const struct A {
              ^
some.cpp:2:5: note: constructor is not user-provided because it is explicitly defaulted in the class body
     A() = default;
     ^
some.cpp:3:9: note: and the implicitly-defined constructor does not initialize ‘int A::x’
     int x;

Достаточно явным образом задать дефолтный конструктор:

const struct A {
    A() : x(0) {};
    int x;
} a;

int main() {}

Как нам объясняет CppReference:

The effects of default initialization are:

  • if T is a non-POD (until C++11) class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;
  • if T is an array type, every element of the array is default-initialized;
  • otherwise, nothing is done: the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.

Ваш случай как раз подпадает под otherwise.

→ Ссылка
Автор решения: KoVadim

Можно инициализировать прямо так.

const struct A {
    int x = 1; // или любое нужное значение
} a;

Способ номер два

const struct A {
    int x;
} a {1};

В данном случае эти способы дадут одинаковый результат. Но второй способ может быть чуточку осложнен, если переменных в классе много-много.

→ Ссылка
Автор решения: user7860670

Независимо от наличия A() = default; поле int x; будет оставаться неинициализированным, а сам класс - trivially constructible. Чтобы этот код заработал, необходимо реализовать дефолтный конструктор, который бы инициализировал поле A(void): a{42} {}, либо оставить класс как есть, но инициализировать объект посредством агрегатной инициализации } a{42};.

→ Ссылка