2012-08-02 16 views
85

Se es C language.It está escrito que:¿Cuál es el significado de "__attribute __ ((embalado, alineado (4)))"

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

Por favor, dime cuál es el significado de la misma, y ​​cómo para usar esta palabra clave

+4

Es un [ "tipo de atributo"] (http: //gcc.gnu. org/onlinedocs/gcc/Type-Attributes.html) .. (Encontré esto con el "atributo C empaquetado" en Google. ¡Seguramente otros pueden al menos funcionar tan bien!) –

+1

Ver [esta pregunta] (http: // stackoverflow. com/q/8568432/827263) - aunque con 'aligned (4)' probablemente no tengas mucho de qué preocuparte. –

Respuesta

102

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


alineación de la estructura de datos es la manera en que se organizan los datos y se accede a ellos en la memoria de la computadora. Consiste en dos problemas separados pero relacionados: alineación de datos y estructura de datos 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, trozos de 4 bytes en un sistema de 32 bits). Alineación de datos significa poner los datos en un desplazamiento de memoria igual a un múltiplo del tamaño de 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 datos estructura relleno.


gcc proporciona la facilidad para evitar el relleno de la 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 relleno estructura. 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 utilizar __attribute__((packed, aligned(X))) insistir en particular (X) de relleno de tamaño. X debe ser poderes de dos.Consulte here

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

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

lo que el atributo especificado anteriormente gcc no permite el relleno estructura. entonces el tamaño será de 8 bytes.

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

#pragma pack(push, 1) 

//Structure 1 
...... 

//Structure 2 
...... 

#pragma pack(pop) 
+5

Si la memoria almacena datos en trozos de 4 bytes, ¿por qué no agrega 2 bytes de relleno al corto sin firmar (su longitud de 2 bytes)? o el compilador solo agrega bytes de relleno a 1er y último miembro de la estructura? ¿Puedes aclararlo? – User

+3

@User Plz refiéranlo también. Si aún no lo tienes claro, por favor, ven a buscar http://stackoverflow.com/questions/11772553/why-padding-is-not-happening-in-this-case – Jeyaram

58
  • packed significa que utilizará el menor espacio posible para struct Ball - es decir, se va a meter campos juntos sin relleno
  • aligned significa que cada struct Ball comenzará en un límite de 4 bytes - es decir, para cualquier struct Ball, su dirección puede ser dividido por 4

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

8

El atributo packed significa que el compilador no agregará relleno entre los campos del struct. El relleno generalmente se usa para alinear los campos con su tamaño natural, ya que algunas arquitecturas imponen penalizaciones por el acceso desalineado o no lo permiten.

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