Конструкторская инициализация встроенных типов - PullRequest
0 голосов
/ 12 июня 2018

Так что в настоящее время я читаю «Язык программирования C ++» Бьярна Страуструпа (великая книга), и в разделе 17.3.1 упоминается, что объект без определенного конструктора и который инициализируется без инициализатора, будет (внестатические случаи) оставляют встроенные типы неопределенными.

У меня есть этот код

#include <iostream>

class A {
public:
    int id;
    // No constructor defined,
    // so default constructor generated
};

void f() {
    A a; // No initializer
    std::cout << a.id << std::endl;
}

int main(int argc, char *argv[]) {
    f();
    return 0;
}

Я ожидаю, что при запуске этого кода будет напечатан мусор, но вместо этого я получу инициализированный(0) значение для a.id.Кроме того, если мы переопределим A так:

class A {
public:
    int id;
    A()=default;
};

Теперь при запуске этого кода a.id будут значениями мусора, как я и ожидал ранее.

Для первогоВ таком случае, почему id член A инициализируется?Почему два случая дают разные результаты?

Я использую g ++ / gcc версии 8.1.0

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

но вместо этого я получаю инициализированное (0) значение для a.id

То, что значение равно 0, не означает, что оно инициализировано.Чтение неинициализированного значения равно неопределенное поведение , поэтому выходные данные могут быть любыми, включая 0.

Если я запускаю этот же код в моей системе, я получаю следующий вывод:

791621423
0 голосов
/ 12 июня 2018

Для первого случая, почему инициализируется член id для A?Почему два случая приводят к разным результатам?

A a; // No initializer

a неинициализировано, и будет иметь неопределенное значение .

Согласно dcl.init / 12

Если для объекта не указан инициализатор, объект является default-initialized .Когда получено хранилище для объекта с автоматическим или динамическим сроком хранения, объект имеет неопределенное значение , и если для объекта не выполняется инициализация, этот объект сохраняет неопределенное значение доэто значение заменяется.

Использование переменных с неопределенными значениями равно неопределенное поведение .

std::cout << a.id << std::endl; // undefined behavior for a.id

Таким образом, в результате получаются разные значения в разных случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...