Search code examples
alignmentdalignof

How to align a struct member in D?


I tried this

struct Foo(T)
{
    align(8) void[T.sizeof] data;
}

but

static assert(Foo!(int).data.alignof == 8);

fails, telling me the alignment is still 1 instead of 8.

Why is this, and how do I fix it, so that it works for any arbitrary alignment that is a power of 2 (not just 8)?


Solution

  • Browsing the DMD source, it looks like alignof doesn't take into account align attributes.

    Here is where it is handled:

    ... if (ident == Id::__xalignof)
    {
        e = new IntegerExp(loc, alignsize(), Type::tsize_t);
    }
    

    This converts a .alignof expression into a size_t expression with value alignsize(), so let's look at alignsize() for a static array:

    unsigned TypeSArray::alignsize()
    {
        return next->alignsize();
    }
    

    It just gets the alignment of the element type (void) in your case.

    void is handled by TypeBasic::alignsize(), which just forwards to TypeBasic::size(0)

    switch (ty)
    {
        ...
        case Tvoid:
            size = 1;
            break;
        ...
    }
    

    Looking at how other types handle alignof, it doesn't look like align attributes are taken into account at all, but I could be wrong. It may be worth testing the alignment manually.