关于'对齐'的困惑属性

时间:2014-06-25 04:31:45

标签: d dmd

我了解align属性具有few different使用形式。

在我的第一次尝试中,我按如下方式使用它:

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

导致结构被填充2个额外的不需要的字节。

将其更改为:

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

我得到了标头大小的预期18个字节。

所以我的疑问是:align属性的第一种形式的实际用途是什么,如果它似乎不像人们期望的那样对齐数据?

1 个答案:

答案 0 :(得分:7)

从你给出的链接中引用:

  

聚合字段的对齐不会影响聚合本身的对齐 - 这会受到聚合外部对齐设置的影响。

因此,第二种形式对齐结构的字段。第一个对齐结构本身。

在您的示例中,考虑更大的对齐 - 例如,16。第一个表单将导致以下布局

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

第二种形式将导致

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