2012-09-06 11 views
6
gcc (GCC) 4.7.0 
c89 
x86_64 

Hola,Estructuras acolchadas que usan __attribute __ (__ packed__), ¿realmente vale la pena?

Me pregunto ¿Merece la pena utilizar mediante el __attribute__ ((__packed__)) en las estructuras. Me parece que con él la estructura será más pequeña en tamaño. Pasando por la prueba que he realizado a continuación. Entonces usarlo sería una ventaja en tamaño.

Un caso para no usarlo, ya que no es portátil en otros compiladores. Entonces, para Visual Studio C++ esto no funcionará. Además de otros compiladores también.

¿El compilador no optimiza el código? ¿De modo que dejar que el compilador decida qué hacer sería mejor para el rendimiento?

¿Utilizaría el atributo alineado alguna diferencia? __attribute__((packed, aligned(4))) Cuando añadí que devuelve el tamaño de 12.

Muchas gracias por todas las sugerencias,

#include <stdio.h> 

struct padded { 
    int age;  /* 4     */ 
    char initial; /* 1 + 3 padded bytes */ 
    int weight; /* 4  --> total = 12 */ 
}; 

struct __attribute__ ((__packed__)) unpadded { 
    int age;  /* 4     */ 
    char initial; /* 1     */ 
    int weight; /* 4 --> total = 9 */ 
}; 

int main(int argc, char **argv) 
{ 
    struct padded padded_test; 
    struct unpadded unpadded_test; 

    printf("Padded [ %ld ]\n", sizeof(struct padded)); 
    printf("Unpadded [ %ld ]\n", sizeof(struct unpadded)); 
    return 0; 
} 
+4

El acceso a la memoria no alineada es más lento – BlackBear

+0

Para su estructura de ejemplo, empaquetarla * y * 4-alinearla es especialmente inútil. No ahorras espacio, solo des-alineas el campo 'peso '. La única razón para hacerlo es hacer coincidir algún diseño preexistente definido de esa manera (e incluso eso supone que usted sabe que la representación del objeto de 'int' en su plataforma es correcta para el campo 'age', etc.). –

Respuesta

13

acceso a memoria no alineado puede ser terriblemente lento en algunas arquitecturas (por ejemplo, IA64, sparc64). __attribute__((__packed__)) está destinado principalmente para su uso cuando está enviando datos a través del cable y desea estar seguro del diseño; no vale la pena intentar usarlo para ahorrar espacio en la memoria.

Si son considerando usar __attribute__((__packed__)) para la transmisión de cables, piénselo de nuevo; no maneja la endianidad, y no es estándar. Escribir el código de clasificación usted mismo es más seguro, y el uso de una biblioteca (por ejemplo, Protocolo Buffers) es más inteligente.

+0

+1, preciso y directo al grano. –

+2

Puede * solo * usar '__packed__' para la transmisión de un formato ya definido (como un protocolo público), que trata sobre endianness por el estilo' htonl'. Pero incluso así, apenas vale la pena, es tan fácil codificar los tamaños y las compensaciones de los campos de forma explícita a medida que escribes una estructura que crees que coincide con la especificación. –

0

Otro uso de __attribute__((packed)) es para acceder a los controladores mapeados en memoria. Como otras personas han sugerido, no es realmente útil a excepción de cosas muy específicas. El acceso desalineado es malo y en algunas arquitecturas genera excepciones.