Как битовые поля взаимодействуют с битовым заполнением в C ++

См. C-версию этого вопроса здесь.

У меня есть два вопроса относительно битовых полей, когда есть биты заполнения.

Скажем, у меня есть структура, определенная как

struct T { 
    unsigned int x: 1; 
    unsigned int y: 1;
};

В структуре T фактически используются только два бита.

Вопрос 1: всегда ли эти два бита являются наименее значимыми битами базового беззнакового int? Или это зависит от платформы?

Вопрос 2: Всегда ли эти неиспользованные 30 бит инициализируются значением 0? Что об этом говорит стандарт C ++?


person John Z. Li    schedule 20.05.2019    source источник


Ответы (2)


Вопрос 1: всегда ли эти два бита являются наименее значимыми битами базового беззнакового int? Или это зависит от платформы?

Очень зависит от платформы. В стандарте даже есть примечание, чтобы уточнить, сколько:

[class.bit]

1 ... Размещение битовых полей внутри класса объект определяется реализацией. Выравнивание битовых полей определяется реализацией. Битовые поля упакованы в некоторую адресуемую единицу распределения. [Примечание: Битовые поля объединяют единицы распределения на одних машинах, но не на других. Битовые поля назначаются справа налево на некоторых машинах, слева направо на других. - конец примечания]

Вы не можете много чего предполагать о компоновке объекта битового поля.

Вопрос 2: Всегда ли эти неиспользованные 30 бит инициализируются значением 0? Что об этом говорит стандарт C ++?

В вашем примере есть простой агрегат, поэтому мы можем перечислить возможные инициализации. Указание без инициализатора ...

T t;

... будет инициализировать его по умолчанию, оставив элементы с неопределенное значение. С другой стороны, если вы укажете пустые фигурные скобки ...

T t{};

... объект будет инициализированным агрегатом, и поэтому битовые поля будут инициализированы самими {} и установлены в ноль. Но это применимо только к элементам агрегата, которые являются битовыми полями. Не указано, какое значение принимают биты заполнения, если они есть. Поэтому мы не можем предполагать, что они будут инициализированы нулем.

person StoryTeller - Unslander Monica    schedule 20.05.2019

Q1: Обычно от низкого до высокого (т.е. x равно 1 ‹---------------- 0, y равно 1 ‹AC 1 и т. Д.).

Q2: значение неиспользуемых битов не определено. На некоторых компиляторах / платформах инициализированные стеком переменные могут сначала быть установлены в ноль (может !!), но не рассчитывайте на это !! Переменные, выделенные в куче, могут быть любыми, поэтому лучше предположить, что биты - мусор. Используя немного нестандартную анонимную структуру, скрытую в объединении, вы можете сделать что-то вроде этого, чтобы гарантировать значение битов:

union T {
 unsigned intval;
 struct { 
   unsigned x : 1;
   unsigned y : 1;
 };
}; 

T foo;
foo.intval = 0;
person robthebloke    schedule 20.05.2019