2014-06-25 15 views
6

Capisco che l'attributo align abbia una forma di utilizzo few different.Confusione relativa all'attributo "align"

Nel mio primo tentativo, stavo usando come segue:

align(1) 
private struct TGAHeader 
{ 
    ubyte idLenght; 
    ubyte hasColormap; 
    ubyte imageType; 
    ushort cmFirstEntry; 
    ushort cmLength;  
    ubyte cmSize;  
    ushort xOrigin;  
    ushort yOrigin;  
    ushort width;   
    ushort height;   
    ubyte pixelDepth;  
    ubyte imageDescriptor; 
} 

// TGAHeader.sizeof == 20 

che ha provocato la struct essere imbottita con 2 byte in più indesiderati.

Dopo aver cambiato a:

private struct TGAHeader 
{ 
align(1): 
    ubyte idLenght; 
    ubyte hasColormap; 
    ubyte imageType; 
    ushort cmFirstEntry; 
    ushort cmLength;  
    ubyte cmSize;  
    ushort xOrigin;  
    ushort yOrigin;  
    ushort width;   
    ushort height;   
    ubyte pixelDepth;  
    ubyte imageDescriptor; 
} 

// TGAHeader.sizeof == 18 

ho ottenuto le previste 18 byte per la dimensione di intestazione.

Quindi il mio dubbio è: qual è l'uso effettivo della prima forma dell'attributo align se non sembra allineare i dati come ci si aspetterebbe?

risposta

7

Citazione dal link che hai dato:

L'allineamento per i campi di un aggregato non influenza l'allineamento del totale in sé - che è influenzato dalla impostazione di allineamento al di fuori dell'aggregato.

Quindi, il secondo modulo allinea i campi della struttura. E il primo allinea la struttura stessa.

Nel tuo esempio, si consideri un allineamento più grande - per esempio, di 16. La prima forma comporterà il seguente layout

TGAHeader.sizeof     = 32 // the padding was added in the end of the struct 
TGAHeader.idLenght.offsetof  = 0 
TGAHeader.hasColormap.offsetof  = 1 
TGAHeader.imageType.offsetof  = 2 
TGAHeader.cmFirstEntry.offsetof = 4 
TGAHeader.cmLength.offsetof  = 6 
TGAHeader.cmSize.offsetof   = 8 
TGAHeader.xOrigin.offsetof   = 10 
TGAHeader.yOrigin.offsetof   = 12 
TGAHeader.width.offsetof   = 14 
TGAHeader.height.offsetof   = 16 
TGAHeader.pixelDepth.offsetof  = 18 
TGAHeader.imageDescriptor.offsetof = 19 

E la seconda forma si tradurrà in

TGAHeader.sizeof     = 192 // every field was padded 
TGAHeader.idLenght.offsetof  = 0 
TGAHeader.hasColormap.offsetof  = 16 
TGAHeader.imageType.offsetof  = 32 
TGAHeader.cmFirstEntry.offsetof = 48 
TGAHeader.cmLength.offsetof  = 64 
TGAHeader.cmSize.offsetof   = 80 
TGAHeader.xOrigin.offsetof   = 96 
TGAHeader.yOrigin.offsetof   = 112 
TGAHeader.width.offsetof   = 128 
TGAHeader.height.offsetof   = 144 
TGAHeader.pixelDepth.offsetof  = 160 
TGAHeader.imageDescriptor.offsetof = 176