Struct alignment vs alignment of fields

Era Scarecrow via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Aug 7 21:16:49 PDT 2014


On Thursday, 7 August 2014 at 17:22:15 UTC, Marc Schütz wrote:
> (Original discussion: 
> http://forum.dlang.org/thread/fckwpddiwxonabqaflqt@forum.dlang.org#post-pskjgieddhpntzaokohj:40forum.dlang.org)

> I would expect `B` to have a gap between `ex` and `mmid`. AFAIK 
> the outer `align(1)` only applies to the struct in its 
> entirety, not to the individual fields. However for both DMD 
> git and LDC 0.14.0-alpha1 (based on DMD 2.065), `A` and `B` 
> have the same size.

> After some thinking, I believe this is because arrays inherit 
> the alignment of their element types. Is this correct? If yes, 
> where is this documented? I had expected `char[4]` to be 
> aligned at a 4-byte boundary.

  I'm not sure about all the latest compiler changes, but let's 
try and answer some of this.

  TDPL pg. 268-269 explains this (although could be out of date 
with recent changes). I'll copy what's relevant..

7.1.11.1 The align Attribute

If you want to override the compiler's choice of alignment, which 
influences the padding inserted. You could use an align 
modifier... etc..

class A {
   char a;
   align(1) int b;
   char c;
}

  With the specification above the fields of A are laid out 
without gaps between them.

  You may use align with an entire class definition:

align(1) struct S {
   char a;
   int b;
   char c
}

  ...
  Align is not suppose to be used with pointers and references...



  Back to the question. Most fields will be aligned on 4-byte 
boundaries, or 8-byte depending on if it's 32/64 bit. This is 
mostly for performance reasons, but also with addresses it may 
affect the GC. Overriding the compiler is mostly going to be more 
useful when working against C/C++ structures where they are also 
forcibly aligned for space.

  So assuming we have the above struct.

  S[2] s;

  It's probably going to be aligned on 4's for the first one; But 
it doesn't have to be. But the others? I'm not so sure... The 
inner alignment and padding is 4 per, so if the struct S has a 
size of 12, then it's still going to be aligned by 4's by 
default... i think? Maybe the alignment has to do if it's 
inserted into another object. On the stack it probably ignores 
the alignment attribute...

struct B {
   char a;
   S s;  //infers align(1) by it's definition?
}

  Well regardless, unless you're overriding both, you're probably 
going to get some form of alignments of 4, be it for arrays or 
for speed... I hope this isn't confusing.


More information about the Digitalmars-d-learn mailing list