Инициализированы ли дополнительные байты на 0 в C ++? - PullRequest
0 голосов
/ 07 мая 2018

Предположим, у меня есть структура, которая содержит int и char:

struct thing_t {
    int value = 0;
    char other_value = 0;
};

Из-за того, как все выровнено в памяти, sizeof(thing_t) должно быть 8, так как размер самого большого элемента составляет 4 байта. Если я создаю инициализированный по умолчанию экземпляр thing_t, будут ли дополнительные 3 байта инициализированы равными 0?

Я понимаю, что обычно это не подходит, но я писал хеш-функцию, и поведение хеш-функции по умолчанию - хеширование универсального типа, как если бы это был массив байтов. Если бы дополнительные байты иногда не инициализировались в 0, я понял, что мой подход может вызвать проблемы.

Ответы [ 3 ]

0 голосов
/ 07 мая 2018

Если я создаю инициализированный по умолчанию экземпляр thing_t, будут ли дополнительные 3 байта инициализированы равными 0?

Они могут или не могут быть. Для них не требуется обнуление.

К сожалению, вы не можете инициализировать значение объекта, чтобы инициализировать его нулем, что обнуляет биты заполнения, потому что инициализаторы-члены по умолчанию мешают его тривиальному конструированию.

[dcl.init] / 8 * 1 010 *

Инициализация значения объекта типа T означает:

[...]

  • если T является (возможно, cv-квалифицированным) типом класса без предоставленного пользователем или удаленного конструктора по умолчанию, то объект инициализируется нулями и проверяются семантические ограничения для инициализации по умолчанию, и если T имеет нетривиальный конструктор по умолчанию, объект инициализируется по умолчанию;

[class.ctor] / 6

Конструктор по умолчанию тривиален, если он не предоставлен пользователем и если:

[...]

  • ни один нестатический член данных в своем классе не имеет инициализатора члена по умолчанию (12.2)
0 голосов
/ 08 мая 2018

Практически говоря: (с учетом других ответов)

Вы должны удалить инициализацию "= 0" из вашей структуры, иначе вы не сможете выполнить инициализацию с нулевым значением или значением (поскольку вы неявно определяете конструктор по умолчанию).

struct thing_t {
    int value;
    char other_value;
};

Тогда вы можете перейти к нулевой инициализации:

thing_t thing = {};

Редактировать: О!Отвечая на ваш вопрос ... Нет, это не так, если только они не являются статическими глобальными переменными, но вы можете использовать инициализацию значение / ноль для достижения этой цели.

0 голосов
/ 07 мая 2018

Я не смог найти ничего в стандарте C ++ 11 о том, что происходит с заполнением, когда объект инициализируется по умолчанию.

Тем не менее, стандарт твердо соответствует заполнению, когда оно наступает инициализация нуля .

С 8.5 Инициализаторы / 5

5,2 & mdash; если T является (возможно, квалифицированным по cv) типом несоединения классов, каждый элемент нестатических данных и каждый подобъект базового класса инициализируются нулями, а заполнение инициализируется нулевыми битами;

5,3 & mdash; если T является (возможно, cv-квалифицированным) типом объединения, первый нестатический именованный элемент данных объекта инициализируется нулями, а заполнение инициализируется нулевыми битами;

Я бы посоветовал использовать нулевую инициализацию вместо инициализации по умолчанию, чтобы принудительно инициализировать биты заполнения нулем. Это приведет к предсказуемым значениям из вашей хеш-функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...