Гарантирует ли стандарт C++ инициализацию байтов заполнения нулевым значением для нестатических агрегатных объектов?C++

Программы на C++. Форум разработчиков
Anonymous
Гарантирует ли стандарт C++ инициализацию байтов заполнения нулевым значением для нестатических агрегатных объектов?

Сообщение Anonymous »

Поддерживает ли C++ языковую конструкцию, которая позволит нам инициализировать объект и все его поля заполнения нулевым значением. На сайте cppreference.com я нашел несколько обнадеживающих формулировок о нулевой инициализации, которые предполагают, что при некоторых условиях байты заполнения также будут обнулены.
Цитата с 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

Вернуться в «C++»