2014-09-13 6 views
10

Я работаю с structs в c на linux. я начал использовать битовые поля и «упаковано» атрибут, и я наткнулся на поведение Wierd:Упакованные битовые поля в c структурах - GCC

struct t1 
{ 
    int a:12; 
    int b:32; 
    int c:4; 
}__attribute__((packed)); 

struct t2 
{ 
    int a:12; 
    int b; 
    int c:4; 
}__attribute__((packed)); 

void main() 
{ 
    printf("%d\n",sizeof(t1)); //output - 6 
    printf("%d\n",sizeof(t2)); //output - 7 
} 

Каким образом обе структуры - которые точно так же - взять diffrent число байтов?

+1

Поскольку 't2 :: b' гарантированно будет отличным местом для хранения данных? Подумайте о гонках данных. –

ответ

10
struct t1 // 6 bytes 
{ 
    int a:12; // 0:11 
    int b:32; // 12:43 
    int c:4; // 44:47 
}__attribute__((packed)); 

struct t1 // 7 bytes 
{ 
    int a:12; // 0:11 
    int b; // 16:47 
    int c:4; // 48:51 
}__attribute__((packed)); 

Обычный int b должен быть выровнен по границе байта. Таким образом, перед ним есть прокладка. Если вы положите c рядом с a, это дополнение больше не понадобится. Вероятно, вы должны это сделать, поскольку доступ к целым числам, не равным байтам, например int b:32, является медленным.

16

Ваши структуры не являются «точно такими же». У вашего первого есть три последовательных битовых поля, второе - одно битовое поле, (не бит-поле) int, а затем второе битовое поле.

Это важно: последовательные (не нулевые ширины) битовые поля объединяются в единую ячейку памяти , в то время как бит-поле, за которым следует небитовое поле, представляют собой различные ячейки памяти.

Ваша первая структура имеет одну ячейку памяти, вторая - три. Вы можете принять адрес члена b во второй структуре, а не в первой. Доступ к участнику b не гоняется с доступом к a или c в вашей второй структуре, но они делают в вашем первом.

Имея небитовое поле (или бит-поле нулевой длины) сразу после того, как член бит-поля «закрывает» его в определенном смысле, то, что будет дальше, будет другим/независимым местоположением/объектом памяти. Компилятор не может «упаковать» ваш член b внутри битового поля, как в первой структуре.