Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion regarding the 'align' attribute

Tags:

d

dmd

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?

like image 289
glampert Avatar asked Jun 25 '14 04:06

glampert


1 Answers

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
like image 188
Sergei Nosov Avatar answered Oct 05 '22 09:10

Sergei Nosov