type c gcc struct bit-fields packed

type - Campos de bits empaquetados en estructuras c-GCC



bit type c (2)

Estoy trabajando con structs en c on linux. Empecé a usar los campos de bits y el atributo "empacado" y encontré un comportamiento extraño:

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 }

¿Cómo es que ambas estructuras (que son exactamente iguales) toman diferentes números de bytes?


Tus estructuras no son "exactamente iguales". El primero tiene tres campos de bits consecutivos, el segundo tiene un campo de bits, un campo int (no bit-field) y luego un segundo campo de bit.

Esto es significativo: los campos de bits consecutivos (ancho distinto de cero) se fusionan en una sola ubicación de memoria , mientras que un campo de bits seguido de un campo que no es de bit son distintas ubicaciones de memoria.

Tu primera estructura tiene una sola ubicación de memoria, tu segunda tiene tres. Puede tomar la dirección del miembro b en su segunda estructura, no en la primera. Los accesos al miembro b no compiten con los accesos de la a o la c en su segunda estructura, pero lo hacen en la primera.

Tener un campo que no sea de bit (o un campo de bit de longitud cero) justo después de que un miembro del campo de bits lo "cierre" en un sentido, lo que sigue será una ubicación / objeto de memoria diferente / independiente. El compilador no puede "empaquetar" su miembro b dentro del campo de bit como lo hace en la primera estructura.


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));

El int b regular debe estar alineado con un límite de bytes. Entonces hay relleno antes de eso. Si coloca c al lado de a, este relleno ya no será necesario. Probablemente deberías hacer esto, ya que el acceso a enteros no alineados con bytes como int b:32 es lento.