[core.reflect] Detect Padding in structs or classes

Stefan Koch uplink.coder at googlemail.com
Fri Oct 1 17:35:24 UTC 2021


There has been a PR to introduce `-vpadding` into dmd which warns 
on padding in structs.
This can actually be trivially done by core reflect.

```D
// detect padding in aggregates
import core.reflect.reflect;
import core.reflect.transitiveVisitor;

struct PadDetctedTuple
{
     string aggregateName;
     ulong number_of_pad_bytes;
}

struct S
{
     ubyte a; // <--- is at offset 0
     ubyte b; // <--- is at offset 1
     // two bytes of padding
     uint d; // <--- is at offset 4
}

static assert(detectPadding(node)[0] == PadDetctedTuple("S", 2)); 
// yes we detected that S has 2 bytes of padding

static assert(S.init.a.offsetof == 0);
static assert(S.init.b.offsetof == 1);
static assert(S.init.d.offsetof == 4);

static immutable sc = currentScope();
static immutable node = nodeFromName("S", ReflectFlags.Members, 
sc);


pragma(msg, detectPadding(node));


PadDetctedTuple[] detectPadding(const Node n)
{
     class PadDetectVisitor : TransitiveVisitor
     {
         alias visit = TransitiveVisitor.visit;

         override void visit(AggregateDeclaration ad)
         {
             ulong lastOffset;
             ulong lastSize;
             ulong wastedBytes;
             foreach(f;ad.fields)
             {
                 wastedBytes += ((f.offset - lastOffset) - 
lastSize);
                 lastOffset = f.offset;
                 lastSize = f.type.size;
             }
             if (wastedBytes)
                 pads ~= PadDetctedTuple(ad.name, wastedBytes);
         }

         PadDetctedTuple[] pads = null;
     }

     scope padDetector = new PadDetectVisitor();
     (cast()n).accept(padDetector);

     return padDetector.pads;
}
```


More information about the Digitalmars-d mailing list