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

Ciao,Strutture imbottite che utilizzano __attribute __ (__ packed__), ne vale davvero la pena?

mi chiedo Ne vale la pena utilizzando utilizzando il __attribute__ ((__packed__)) sulle strutture. Mi sembra che con esso la struttura sarà più piccola. Passando alla prova che ho eseguito di seguito. Quindi utilizzarlo sarebbe un vantaggio in termini di dimensioni.

Un caso per non utilizzarlo, in quanto non è portatile su altri compilatori. Quindi per Visual Studio C++ questo non funzionerà. Più altri compilatori pure.

Il compilatore non ottimizza il codice? Quindi lasciare che sia il compilatore a decidere cosa fare sarebbe meglio per le prestazioni?

L'utilizzo dell'attributo allineato farebbe alcuna differenza? __attribute__((packed, aligned(4))) Quando ho aggiunto che restituito la dimensione di 12.

Grazie per eventuali suggerimenti,

#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

L'accesso alla memoria non allineato è più lento – BlackBear

+0

Per la struttura di esempio, l'imballaggio * e * l'allineamento a 4 è particolarmente vantaggioso. Non si salva spazio, si disallinea il campo 'peso'. L'unica ragione per farlo è abbinare un layout preesistente definito in questo modo (e anche questo presuppone che tu sappia che la rappresentazione dell'oggetto di 'int' sulla tua piattaforma è corretta per il campo' age', ecc.). –

risposta

13

accesso alla memoria Unaligned può essere horrendously lento su alcune architetture (ad esempio ia64, sparc64). __attribute__((__packed__)) è principalmente destinato all'uso in cui si inviano i dati sul filo e si vuole essere certi del layout; non vale la pena provare a usarlo per risparmiare spazio in memoria.

Se si sono considerando l'utilizzo di __attribute__((__packed__)) per la trasmissione via cavo, ripensateci; non gestisce l'endianità e non è standard. Scrivere il codice di marshalling da soli è più sicuro e utilizzare una libreria (ad esempio, Protocol Buffers) è più intelligente.

+0

+1, preciso e dritto al punto. –

+2

È possibile * solo * utilizzare '__packed__' per la trasmissione di un formato già definito (come un protocollo pubblico), che si occupa di endianness di' htonl'. Ma anche a quel punto non vale la pena, sei anche in grado di codificare le dimensioni e gli offset dei campi in modo esplicito mentre stai scrivendo una struttura che ritieni adatta alle specifiche. –

0

Un altro utilizzo di __attribute__((packed)) è per l'accesso ai controller mappati in memoria. Come altre persone hanno suggerito, non molto utile se non per cose molto specifiche. L'accesso non allineato è errato e su alcune architetture genera eccezioni.