2014-11-03 2 views
6

Fount этого утверждение нулевой длиной битового поле может вызвать следующее поле, чтобы быть выровнено по границе следующего контейнера, когда контейнер имеет такой же размер, как основной тип битового поляРазличные типы битовых полей нулевой длины в c?

Для того, чтобы поместить его на практику предполагая, что int - 2 байта (16 бит), и что короткий - 1 байт (8 бит), чтобы сохранить ввод. Также предположим, что мы используем компилятор gcc (было бы неплохо объяснить различия в clang).

struct foo { 
    unsigned int a:5; 
    unsigned int :0; 
    unsigned int b:3; 
} 

В памяти это выглядит как

struct address 
    |    
    | 
    v 
    aaaaa000 00000000 bbb00000 00000000 

Вопрос 1: В моем понимании это может не выглядеть aaaaa000 00000000 0..00bbb00000..., так bbb должен согласовать с контейнером непосредственно после текущего контейнера. Это правда?

Двигаясь дальше, если я указываю

struct bar { 
    unsigned short x:5; 
    unsigned int :0; 
    unsigned short y:7; 
} 

Будет ли это как так?

struct address 
    | short stops here   short starts 
    |  |     | 
    v  v | this is uint | v    
    xxxxx000 00000000 00000000 yyyyyyy0 

Edit 1 Было отмечено, что короткие не может быть меньше, чем 16 байт. Это немного рядом с вопросом в этом вопросе. Но если его важна для вас, вы можете заменить short с char и int с short

+0

Какой компилятор? Битовые поля имеют множество специфических для реализации деталей. –

+0

@CarlNorum отредактировал вопрос. – user10607

+0

Даже битовые поля получают отступы для выравнивания во время переключателей типов, поэтому ваш образец неправильный. –

ответ

1

Update, после прочтения текста in context:

Результат вашего примера (исправленный использовать char):

struct bar { 
    unsigned char x:5; 
    unsigned int :0; 
    unsigned char y:7; 
} 

будет выглядеть следующим образом (предполагается, что 16-разрядные int):

char pad pad  int boundary 
    | | |  | 
    v v v  v  
    xxxxx000 00000000 yyyyyyy0 

(Я игнорирую endian).

Поле бит нулевой длины вызывает перемещение позиции до следующей границы int. Вы определили int как 16-бит, поэтому 16 минус 5 дает 11 бит отступов.

Это не Вставить весь пробел int. Пример на странице, на которую вы ссылаетесь, демонстрирует это (но с использованием 32-битных целых чисел).

+0

Вот ссылка для контекста http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03defbitf.htm – user10607

+0

Я сделал еще немного чтения, и ваш ответ хорошо подходит к большой картине. Благодаря! – user10607

-1

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

Это то, что я думаю.

struct address 
| short stops here   short starts 
| |     | 
v v| this is unit  | v    
xxxxx000 00000000 00000000 yyyyyyy0 
+5

Во-первых, я не верю, что это действительная рекомендация * если * ваша единственная цель - свести к минимуму пространство. Иногда битовые поля используются для соответствия внешнему макету. Во-вторых, я не верю, что это отвечает на вопрос. –

Смежные вопросы