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

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

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

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

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

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

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

1 Ответ

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

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

Нет, это зависит как от системы, так и от компилятора.Вы никогда не можете предполагать или знать, что они являются MSB или LSB.

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

Зависит от того, как вы инициализируете структуру.Структура в локальной области видимости, которая не инициализирована, может содержать значения мусора в битах / байтах заполнения.Структура, которая инициализируется хотя бы одним набором инициализаторов, гарантированно будет содержать ноль даже в байтах заполнения: my_struct = { something };.


Sources

Язык- подробности юриста о том, почему вышеуказанные работы несколько сложны.

C17 6.7.9 / 9 (выделено мной) говорит следующее:

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

Это означает, что мы вообще не можем доверять битам / байтам заполнения.Но есть и следующее исключение из вышеприведенного правила (выделенное в §20):

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

Это означает, что если есть хотя бы один инициализатор, то применяется следующее правило статической инициализации хранилища:

C17 6.7.9 / 10 (выделено мной):

Если объект со статическим или потоком сроком хранения явно не инициализирован, то: / - /

  • , если этоВ совокупности каждый элемент инициализируется (рекурсивно) в соответствии с этими правилами, и любое заполнение инициализируется нулевыми битами ;
...