Nel linguaggio C le strutture (struct) possono includere altre strutture e vari tipi di dati. Tuttavia, la disposizione dei campi all'interno della struttura può influenzare la sua dimensione e l'allineamento. Il compilatore aggiunge byte extra (padding) per rispettare l'allineamento (alignment) del campo più grande. Questo è importante per le prestazioni e il corretto funzionamento del processore.
Se una struttura contiene strutture annidate, l'allineamento si applica in modo ricorsivo:
#pragma pack in MSVC o l'attributo __attribute__((packed)) in GCC/Clang).Esempio:
#include <stdio.h> struct Inner { char c; int x; }; struct Outer { char a; struct Inner b; short s; }; int main() { printf("sizeof(struct Inner) = %zu\n", sizeof(struct Inner)); printf("sizeof(struct Outer) = %zu\n", sizeof(struct Outer)); return 0; } // sizeof(struct Inner) = 8 (su 64 bit), sizeof(struct Outer) = 16 o 24
L'uso di pack e packed riduce la dimensione ignorando l'allineamento, ma può ridurre le prestazioni o causare errori su alcune piattaforme (ARM, DSP, ecc.).
Domanda: È possibile garantire la stessa dimensione della stessa struttura su tutte le piattaforme?
Risposta: No! Lo standard C non garantisce lo stesso allineamento, l'ordine dei byte (endian), e può "aggiungere" padding tra i campi e alla fine della struttura. Per la compatibilità binaria delle strutture è necessario utilizzare il controllo manuale dell'allineamento e testare sempre esplicitamente sizeof su ciascuna piattaforma target.
Esempio:
struct Data { char c; int x; }; // sizeof(Data) di solito è 8 su 64 bit, 5 o 8 su 32 bit
Storia
Durante lo scambio di una struttura tra un microcontrollore (ARM) e un PC tramite un protocollo binario, i dati provenienti da ARM non corrispondevano alle aspettative sul PC — a causa di un diverso padding e ordine dei byte. Questo portava a decodificare parametri errati, causando errori fisici nel controllo del dispositivo.
Storia
In un protocollo di rete, per accelerare l'invio dei dati sono state aggiunte strutture packed, ma non si è tenuto conto che su piattaforme senza allineamento alcuni campi non funzionavano (il processore non supportava l'accesso non allineato). Risultato: eccezioni hardware durante l'elaborazione dei pacchetti di rete.
Storia
Un server lavorava con un file esterno composto da registrazioni di struttura. Dopo l'aggiornamento del compilatore, la dimensione della struttura è cambiata (un diverso allineamento). I vecchi dati nel file hanno smesso di essere letti correttamente, parte delle informazioni è diventata "rovinata".