Thread overview
Struct members align in DMD 2.060
Oct 07, 2012
novice2
Oct 07, 2012
novice2
Oct 07, 2012
Maxim Fomin
Oct 07, 2012
novice2
Oct 07, 2012
Maxim Fomin
Oct 07, 2012
novice2
Oct 07, 2012
novice2
Oct 07, 2012
Maxim Fomin
October 07, 2012
Some of my code broken in DMD 2.060.
I need packed struct without align to process data.
Is this bug or something changed in 2.060 ?
Code http://dpaste.dzfl.pl/212ca53b :

import std.stdio;

align(1) struct S1
{
  char[2]  c;  //+0
  uint     u;  //+2
}

struct S2
{
  align(1):
  char[2]  c;  //+0
  uint     u;  //+2
}

struct S3
{
  align(1) char[2]  c;  //+0
  align(1) uint     u;  //+2
}

void main()
{
  writeln("**** compiler ",__VENDOR__, " ", __VERSION__);
  writeln;

  writeln("S1.c.offsetof (should be 0) = ", S1.c.offsetof);
  writeln("S1.u.offsetof (should be 2) = ", S1.u.offsetof);
  writeln("S1.sizeof (should be 6) = ", S1.sizeof);
  writeln;

  writeln("S2.c.offsetof (should be 0) = ", S2.c.offsetof);
  writeln("S2.u.offsetof (should be 2) = ", S2.u.offsetof);
  writeln("S2.sizeof (should be 6) = ", S2.sizeof);
  writeln;

  writeln("S3.c.offsetof (should be 0) = ", S3.c.offsetof);
  writeln("S3.u.offsetof (should be 2) = ", S3.u.offsetof);
  writeln("S3.sizeof (should be 6) = ", S3.sizeof);
  writeln;
}


Output:

**** compiler Digital Mars D 2059

S1.c.offsetof (should be 0) = 0
S1.u.offsetof (should be 2) = 2
S1.sizeof (should be 6) = 6

S2.c.offsetof (should be 0) = 0
S2.u.offsetof (should be 2) = 2
S2.sizeof (should be 6) = 6

S3.c.offsetof (should be 0) = 0
S3.u.offsetof (should be 2) = 2
S3.sizeof (should be 6) = 6


**** compiler Digital Mars D 2060

S1.c.offsetof (should be 0) = 0
S1.u.offsetof (should be 2) = 4
S1.sizeof (should be 6) = 8

S2.c.offsetof (should be 0) = 0
S2.u.offsetof (should be 2) = 2
S2.sizeof (should be 6) = 8

S3.c.offsetof (should be 0) = 0
S3.u.offsetof (should be 2) = 2
S3.sizeof (should be 6) = 8

October 07, 2012
btw GDC and LDC 2.060 produces same output as DMD 2.060 at http://dpaste.dzfl.pl/
October 07, 2012
http://dlang.org/changelog.html

Since 2.060 behavior of align outside aggregate was changed. This explains the first example. Regarding the second one: "alignment for the fields of an aggregate doesn't affect the alignment of the aggregate itself" - from spec http://dlang.org/attribute.html#align.
October 07, 2012
Thanx Maxim,
but what about

S2.sizeof (should be 6) = 8

S3.sizeof (should be 6) = 8
October 07, 2012
On Sunday, 7 October 2012 at 10:45:40 UTC, novice2 wrote:
> Thanx Maxim,
> but what about
>
> S2.sizeof (should be 6) = 8
>
> S3.sizeof (should be 6) = 8

http://dpaste.dzfl.pl/57911897

Alignment attribute specifies members' alignment if it is inside structure and structure alignment if it is placed outside it. In case of S2 and S3 u member is placed without alignment and both structures contain 2+4 bytes, but because structures themselves are not specified with align() attribute, they are aligned to default 4 byte boundary and contain additional 2 trailing bytes. S4 is specified as having no alignment, so it's size is exactly 2+4 bytes.
October 07, 2012
Thanx again.
Code align(1) struct ... { align(1): ... }
rescue me and return pre 2.060 behaviour
October 07, 2012
> and contain additional 2 trailing bytes

But, imho, this is "unproperly" to include something outside struct in its size.

October 07, 2012
On Sunday, 7 October 2012 at 12:42:17 UTC, novice2 wrote:
>> and contain additional 2 trailing bytes
>
> But, imho, this is "unproperly" to include something outside struct in its size.

Strictly speaking, nothing special is included, just empty bytes for optimization purposes. This behavior is similar to C/C++ where structures can have internal and trailing padding.