Цитата с cppreference.com: нулевая инициализация< /p>
Инициализация нуля выполняется в следующих ситуациях:
[*]Как часть последовательности инициализации значений для типов, не являющихся классами, и для членов типов классов, инициализируемых значением, у которых нет конструкторов, включая инициализацию значений элементов агрегатов, для которых не предусмотрены инициализаторы.
Эффекты нулевой инициализации:
- Если T — скалярный тип, начальным значением объекта является явная целочисленная константа ноль. преобразуется в T.
- Если T не является типом класса, не являющегося объединением, все базовые классы и нестатические элементы данных инициализируются нулями, а все заполнения инициализируются нулевыми битами. Конструкторы, если таковые имеются, игнорируются.
- ...
Я тестировал с использованием довольно последних компиляторов GCC и clang C++, и их поведение кажется различным.< /p>
Честно говоря, я очень старался разобрать эти правила, особенно учитывая разное поведение компилятора, так и не смог понять, как правильно интерпретировать эти правила.
См. код здесь (требуется минимум C++11). И вот результаты:
Дано: Фу
Код: Выделить всё
struct Foo
{
char x;
int y;
char z;
};
Construct
g++
clang++
Foo()
Код: Выделить всё
x:[----][0x42][0x43][0x44],v: 0Код: Выделить всё
x:[----][----][----][----],v: 0Код: Выделить всё
y:[----][----][----][----],v: 0Код: Выделить всё
y:[----][----][----][----],v: 0Код: Выделить всё
z:[----][0x4A][0x4B][0x4C],v: 0Код: Выделить всё
z:[----][----][----][----],v: 0< td>
Фу{}
Код: Выделить всё
x:[----][----][----][----],v: 0Код: Выделить всё
x:[----][0x42][0x43][0x44],v: 0Код: Выделить всё
y:[----][----][----][----],v: 0Код: Выделить всё
y:[----][----][----][----],v: 0Код: Выделить всё
z:[----][----][----][----],v: 0Код: Выделить всё
z:[----][0x4A][0x4B][0x4C],v: 0Здесь [- ---] представляет собой байт, содержащий все биты 0, а [0x..] является мусорным значением.
Как вы можете видеть, выходные данные компилятора показывают, что дополнение не инициализируется. И Foo(), и Foo{} являются инициализацией значений. Кроме того, Foo{} представляет собой агрегатную инициализацию с отсутствующими инициализаторами. Почему не срабатывает правило нулевой инициализации? Почему не срабатывает правило заполнения?
Я уже понимаю, что полагаться на то, что байты заполнения будут равны нулю, не является хорошей идеей или даже может быть неопределенным поведением, но я думаю, что это не касается точку этого вопроса.
- Вопрос 1: Предоставляет ли стандарт способ надежной инициализации байтов заполнения?
- Вопрос 2: Также см.: инициализирует ли c заполнение структуры. Применимо ли это?
- Вопрос 3: Соответствуют ли эти компиляторы стандартам?
- Вопрос 4: Чем объясняется явно отклоняющееся поведение компилятора ?
Подробнее здесь: https://stackoverflow.com/questions/709 ... ro-for-non