c++11 - нулевая инициализация членов вместо default-init

В приведенном ниже коде я ожидаю, что члены будут инициированы с помощью gargabe, поскольку они не упоминаются в списке членов-инициалов вызываемого конструктора (с двумяintпараметры). Вместо этого я постоянно получаю0в обоихiиjизa,bиcи я не понимаю, почему. Может ли кто-нибудь указать мне правильное направление?

      #include <iostream>
#include <type_traits>


class A {
    public:
        int i;
        int j;
        A() = delete;
        A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};

int
smear_stack(int p)
{
    int j = p++;
    int a[500] = {};
    for(int i = 0; i < 499; i++) {
        a[i] = ++j;
    }
    std::cout << j << std::endl;
    return ++j;
}

int main(void)
{
    int i = 2;
    i = smear_stack(++i);

    A a  (i, 32 );
    std::cout << "a is " << a.i << " " << a.j << std::endl;

    A b = { a };
    std::cout << "b is " << b.i << " " << b.j << std::endl;

    A c = { a.i, a.j };
    std::cout << "c is " << c.i << " " << c.j << std::endl;
}

1 ответ

The iиjполя, к которым вы обращаетесь, действительно не инициализированы. Однако вы размазываете не ту часть стека. Так уж получилось, что в большинстве ОС стек изначально состоит из одних нулей. Раньше даже в C было принято (давным-давно) предполагать, что автоматические переменные вmainбыли инициализированы нулями.

Чтобы увидеть, что память действительно неинициализирована, достаточно положить туда что-то еще. Вот пример:

      #include <iostream>
#include <memory>

class A {
public:
    int i;
    int j;
    A() = delete;
    A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};

union U {
    int is[2];
    A a;
    U() : is{3,4} {}
};

int
main()
{
    U u;
    std::construct_at(&u.a, 5, 6);
    std::cout << u.a.i << ", " << u.a.j << std::endl;
    // output:
    // VOLOLO!
    // 3, 4
}
Другие вопросы по тегам