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
}