169 lines · cpp
1// Compile with "cl /c /Zi /GR- SimplePaddingTest.cpp"2// Link with "link SimplePaddingTest.obj /debug /nodefaultlib /entry:main"3 4#include <stdint.h>5 6extern "C" using at_exit_handler = void();7 8int atexit(at_exit_handler handler) { return 0; }9 10struct SimplePadNoPadding {11 int32_t X;12 int32_t Y;13 // No padding anywhere, sizeof(T) = 814} A;15 16struct SimplePadUnion {17 union {18 int32_t X;19 int64_t Y;20 struct {21 int32_t X;22 // 4 bytes of padding here23 int64_t Y;24 } Z;25 };26 // Since the padding occurs at a location that is occupied by other storage27 // (namely the Y member), the storage will still be considered used, and so28 // there will be no unused bytes in the larger class. But in the debug29 // info for the nested struct, we should see padding.30 // sizeof(SimplePadUnion) == sizeof(Z) == 1631} B;32 33struct SimplePadNoPadding2 {34 bool A;35 bool B;36 bool C;37 bool D;38 // No padding anywhere, sizeof(T) = 439} C;40 41struct alignas(4) SimplePadFields1 {42 char A;43 char B;44 char C;45 // 1 byte of padding here, sizeof(T) = 446} E;47 48struct SimplePadFields2 {49 int32_t Y;50 char X;51} F;52 53struct SimplePadBase {54 // Make sure this class is 4 bytes, and the derived class requires 8 byte55 // alignment, so that padding is inserted between base and derived.56 int32_t X;57 // No padding here58} G;59 60struct SimplePadDerived : public SimplePadBase {61 // 4 bytes of padding here due to Y requiring 8 byte alignment.62 // Thus, sizeof(T) = 1663 int64_t Y;64} H;65 66struct SimplePadEmptyBase1 {};67struct SimplePadEmptyBase2 {};68 69struct SimplePadEmpty : public SimplePadEmptyBase1, SimplePadEmptyBase2 {70 // Bases have to occupy at least 1 byte of storage, so this requires71 // 2 bytes of padding, plus 1 byte for each base, yielding sizeof(T) = 872 int32_t X;73} I;74 75struct SimplePadVfptr {76 virtual ~SimplePadVfptr() {}77 static void operator delete(void *ptr, size_t sz) {}78 int32_t X;79} J;80 81struct NonEmptyBase1 {82 bool X;83};84 85struct NonEmptyBase2 {86 bool Y;87};88 89struct SimplePadMultiInherit : public NonEmptyBase1, public NonEmptyBase2 {90 // X and Y from the 2 bases will get squished together, leaving 2 bytes91 // of padding necessary for proper alignment of an int32.92 // Therefore, sizeof(T) = 2 + 2 + 4 = 893 int32_t X;94} K;95 96struct SimplePadMultiInherit2 : public SimplePadFields1, SimplePadFields2 {97 // There should be 1 byte of padding after the first class, and98 // 3 bytes of padding after the second class.99 int32_t X;100} L;101 102struct OneLevelInherit : public NonEmptyBase1 {103 short Y;104};105 106struct SimplePadTwoLevelInherit : public OneLevelInherit {107 // OneLevelInherit has nested padding because of its base,108 // and then padding again because of this class. So each109 // class should be 4 bytes, yielding sizeof(T) = 12.110 int64_t Z;111} M;112 113struct SimplePadAggregate {114 NonEmptyBase1 X;115 int32_t Y;116 // the presence of X will cause 3 bytes of padding to be injected.117 SimplePadFields1 Fields;118} N;119 120struct SimplePadVtable1 {121 static void operator delete(void *ptr, size_t sz) {}122 virtual ~SimplePadVtable1() {}123 virtual void A1() {}124 virtual void B1() {}125} O;126 127struct SimplePadVtable2 {128 static void operator delete(void *ptr, size_t sz) {}129 virtual ~SimplePadVtable2() {}130 virtual void X2() {}131 virtual void Y2() {}132 virtual void Z2() {}133} P;134 135struct SimplePadVtable3 {136 static void operator delete(void *ptr, size_t sz) {}137 virtual ~SimplePadVtable3() {}138 virtual void Foo3() {}139 virtual void Bar3() {}140 virtual void Baz3() {}141 virtual void Buzz3() {}142} Q;143 144struct SimplePadMultiVTables145 : public SimplePadVtable1,146 public SimplePadVtable2,147 public SimplePadVtable3 {148 149 ~SimplePadMultiVTables() override {}150 static void operator delete(void *ptr, size_t sz) {}151 152 // SimplePadVtable1 overrides153 void A1() override {}154 155 // SimplePadVtable2 overrides156 void Y2() override {}157 void Z2() override {}158 159 // SimplePadVtable3 overrides160 void Bar3() override {}161 void Baz3() override {}162 void Buzz3() override {}163} R;164 165int main(int argc, char **argv) {166 167 return 0;168}169