¿Cuál es el significado de "__ atributo __ ((empaquetado, alineado (4)))"

122

Es lenguaje C. Está escrito que:

typedef struct __attribute__((packed, aligned(4))) Ball {
    float2 delta;
    float2 position;
    //float3 color;
    float size;
    //int arcID;
    //float arcStr;
} Ball_t;
Ball_t *balls;

Dígame cuál es su significado y cómo usar esta palabra clave.

Aaron Lee
fuente
44
Es un "atributo de tipo" .. (me encontré con este "atributo C lleno" en Google Seguramente al menos otros pueden hacer lo bueno.!)
1
Vea esta pregunta , aunque aligned(4)probablemente no tenga mucho de qué preocuparse.
Keith Thompson

Respuestas:

157

Antes de responder, me gustaría darle algunos datos de Wiki


La alineación de la estructura de datos es la forma en que los datos se organizan y acceden en la memoria de la computadora. Se compone de dos cuestiones distintas pero relacionadas: la alineación de datos y los datos de estructura de relleno .

Cuando una computadora moderna lee o escribe en una dirección de memoria, lo hará en fragmentos de tamaño de palabra (por ejemplo, fragmentos de 4 bytes en un sistema de 32 bits). La alineación de datos significa colocar los datos en un desplazamiento de memoria igual a un múltiplo del tamaño de la palabra, lo que aumenta el rendimiento del sistema debido a la forma en que la CPU maneja la memoria.

Para alinear los datos, puede ser necesario insertar algunos bytes sin sentido entre el final de la última estructura de datos y el comienzo de la siguiente, que es el relleno de la estructura de datos .


gcc proporciona funcionalidad para deshabilitar el relleno de estructura. es decir, para evitar estos bytes sin sentido en algunos casos. Considere la siguiente estructura:

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}sSampleStruct;

sizeof(sSampleStruct)será 12 en lugar de 8. Debido a la estructura de relleno. De forma predeterminada, en X86, las estructuras se rellenarán con una alineación de 4 bytes:

typedef struct
{
     char Data1;
     //3-Bytes Added here.
     int Data2;
     unsigned short Data3;
     char Data4;
     //1-byte Added here.

}sSampleStruct;

Podemos usar __attribute__((packed, aligned(X)))para insistir en el relleno de tamaño particular (X). X debe ser potencia de dos. Consulte aquí

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}__attribute__((packed, aligned(1))) sSampleStruct;  

entonces el atributo gcc especificado arriba no permite el relleno de la estructura. entonces el tamaño será de 8 bytes.

Si desea hacer lo mismo para todas las estructuras, simplemente podemos empujar el valor de alineación para apilar usando #pragma

#pragma pack(push, 1)

//Structure 1
......

//Structure 2
......

#pragma pack(pop)
Jeyaram
fuente
66
Si la memoria almacena datos en fragmentos de 4 bytes, ¿por qué no agrega 2 bytes de relleno al corto sin signo (su longitud de 2 bytes)? ¿O el compilador simplemente agrega bytes de relleno al primer y último miembro de la estructura? ¿Puedes por favor aclararlo?
Usuario
55
@Usuario Por favor, consulte esto también. Si aún no lo tiene claro, por favor venga a buscar ayuda stackoverflow.com/questions/11772553/…
Jeyaram
Quien dijo que estos bytes de relleno no tienen sentido no sabe que el acceso a datos desalineados es una rareza de la arquitectura x86. Estos bytes son necesarios para evitar excepciones cuando el procesador intenta cargar, digamos un número entero, datos que se extienden a horcajadas sobre su límite de alineación natural.
Tanveer Badar
86
  • packedsignifica que usará el espacio más pequeño posible struct Ball, es decir, agrupará los campos sin relleno
  • alignedsignifica que cada uno struct Ballcomenzará en un límite de 4 bytes, es decir, para cualquiera struct Ball, su dirección se puede dividir por 4

Estas son extensiones GCC, no forman parte de ningún estándar C.

cnicutar
fuente
17

El atributo packedsignifica que el compilador no agregará relleno entre los campos de struct. El relleno generalmente se usa para alinear los campos a su tamaño natural, porque algunas arquitecturas imponen penalizaciones por acceso no alineado o no lo permiten en absoluto.

aligned(4) significa que la estructura debe estar alineada con una dirección que es divisible por 4.

Julian Stecklina
fuente