Как битовые поля взаимодействуют с заполнением битов в C ++ - PullRequest
6 голосов
/ 20 мая 2019

См. Версию C этих вопросов здесь .

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

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

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 20 мая 2019

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

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

[class.bit]

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

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

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

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

T t;

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

T t{};

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

2 голосов
/ 20 мая 2019

Q1: обычно от низкого к высокому (т. Е. X равен 1 << 0, y равен 1 << 1 и т. Д.). </p>

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

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

T foo;
foo.intval = 0;
...