Confusion regarding the 'align' attribute
Asked Answered
C

1

6

I understand that the align attribute has a few different form of use.

In my first attempt, I was using it as follows:

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

Which resulted in the struct being padded with 2 extra unwanted bytes.

After changing it to:

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

I got the expected 18 bytes for the header size.

So my doubt is: What is the actual use of the first form of the align attribute if it doesn't seem to align the data as one would expect?

Cravat answered 25/6, 2014 at 4:31 Comment(0)
C
7

Quote from the link you've given:

The alignment for the fields of an aggregate does not affect the alignment of the aggregate itself - that is affected by the alignment setting outside of the aggregate.

So, the second form aligns the fields of the struct. And the first aligns the struct itself.

In your example, consider a bigger alignment - say, of 16. The first form will result in the following 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

And the second form will result 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
Coriolanus answered 25/6, 2014 at 6:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.