www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 17277] New: Member and aggregate alignment semantics

https://issues.dlang.org/show_bug.cgi?id=17277

          Issue ID: 17277
           Summary: Member and aggregate alignment semantics
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: kinke gmx.net

Code:

*****
struct S
{
    byte[5] bytes;
    struct {
        byte byte1;
        align(1) int int1;
    }
}

pragma(msg, "S.int1.offsetof: ", S.int1.offsetof);
pragma(msg, "S.alignof: ", S.alignof);
pragma(msg, "S.sizeof: ", S.sizeof);
*****

Result:
S.int1.offsetof: 9LU
S.alignof: 4LU
S.sizeof: 16LU

I expected { 6, 1, 10 }. `byte1` has an implicit alignment of 1 as it's a byte,
`int1` has an explicit alignment of 1. I'd expect the anonymous struct's
implicit alignment to be max(1, 1) = 1 (maximum of all member alignments). As
the `bytes` array has an implicit alignment of 1 too, I'd expect S to have an
implicit alignment of max(1, 1) = 1 too. And so both the anonymous struct and S
aren't padded.

Just for clarifiction, in this modified version:

struct S
{
    byte[5] bytes;
    struct {
        byte byte1;
        align(2) int int1;
    }
}

I'd expect { 8, 2, 12 } with 2 padding bytes at offsets 5 and 7.

-----

When adding an explicit align(1) for both anonymous struct and S:

align(1) struct S
{
    byte[5] bytes;
    align(1) struct {
        byte byte1;
        align(1) int int1;
    }
}

you still don't come up with { 6, 1, 10 }. It's { 6, 4, 10 }. I.e., S's
alignment is 4, but it's size is 10. Which means that every odd element in an
array of S structs is **guaranteed** NOT to be aligned on a 4-bytes-boundary.

Note that LDC uses these alignments as optimization hints for LLVM codegen, and
platforms such as ARM don't forgive unaligned memory access.

--
Mar 26 2017