В каких случаях происходит инициализация нулями и в каких нет?
-
Смотря чего. Для инициализации участка памяти, например, существуют функции стандартной библиотеки(calloc как альтернатива malloc, к примеру). – AseN Jan 25 '16 at 08:41
-
Мне интересны все возможные случаи инициализации в с++, гугл не помог или я не так гуглил. – Kioqps Jan 25 '16 at 08:51
-
2А мне вот помог гугл – ixSci Jan 25 '16 at 08:56
-
Ну там же не все случаи. – Kioqps Jan 25 '16 at 09:01
3 Answers
Инициализация нулями (zero-initialization) применяется в трех случаях:
1) Переменные со статическим и потоковым временем хранения (static/thread storage duration), перед тем как для них производится любая другая инициализация.
Сюда входят переменные, объявленные с помощью ключевых слов thread_local, static, а также глобальные переменные.
thread_local int a;
int b;
struct S {
void f() {
static int c;
}
static int d;
};
int S::d;
2) При инициализации значением (value-initialization), если тип не является классом (class или struct), и не является массивом.
union U { int a; float b; };
void f(int, U);
f(int(), U());
3) Элементы массива char, для которых нет инициализаторов:
char a[5] = "123"; // a[3] и a[4] будут использованы нулями.
Более подробно можно прочитать на cppreference.
- 31,143
-
-
-
@Abyx en.cppreference.com/w/cpp/language/default_initialization, там пишут object в таком странном контексте как будто это понятие включает в себя и класс и обычный примитивный тип. Верно ли это? – Kioqps Jan 25 '16 at 13:44
-
1@Kioqps, да это нормально: «The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is a region of storage.» Standard C++ [intro.object] p1 – ixSci Jan 25 '16 at 13:55
-
@ixSci , я нашел стандарт с++, но никак не могу найти раздел об инициализаторах. Ткните пожалуйста, умоляю :D – Kioqps Jan 25 '16 at 15:16
-
1@Kioqps, поиск по pdf ->intro.object. Ну или секция 1.8, самый первый пункт. – ixSci Jan 25 '16 at 15:17
-
@ixSci , а чем отличается variable от object? Тем что variable именованная? – MrPrank Jan 25 '16 at 19:08
-
Нулями инициализируются переменные, расположенные в статической памяти, а переменные, расположенные в автоматической памяти (стеке) не инициализируются.
- 1,136
- 10
- 22
-
При обьявлении класса в стеке (локального, не ссылки на класс) вызывается конструктор класса. Если конструктор делает "очистку", то да. – nick_n_a Jan 25 '16 at 10:14
Самый заковыристый момент с конструкторами по-умолчанию. Если конструктор по-умолчанию определен компилятором неявно, то при вызове его со скобками зануление выполняется, а без скобок не выполняется.
У меня на эту тему была проблема с классом std::array который по стандарту не имеет каких-либо явных конcтрукторов. Так вот, следующий код ожидал зануление и был ошибочный:
typedef std::array<unsigned char, 16> Bytes;
auto block = Bytes; // в массиве муссор
А этот правильный:
auto block = Bytes(); // в массиве нули
Правда в моем случае дело усугубилось еще и тем, что волшебный VC2012 в отладочной сборке выполнял зануление для первого варианта, а в выпускной нет. Поэтому я не сразу догадался проверить конструктор.
- 6,863