1 // Compile with "cl /c /Zi /GR- SimplePaddingTest.cpp"
2 // Link with "link SimplePaddingTest.obj /debug /nodefaultlib /entry:main"
6 extern "C" using at_exit_handler
= void();
8 int atexit(at_exit_handler handler
) { return 0; }
10 struct SimplePadNoPadding
{
13 // No padding anywhere, sizeof(T) = 8
16 struct SimplePadUnion
{
22 // 4 bytes of padding here
26 // Since the padding occurs at a location that is occupied by other storage
27 // (namely the Y member), the storage will still be considered used, and so
28 // there will be no unused bytes in the larger class. But in the debug
29 // info for the nested struct, we should see padding.
30 // sizeof(SimplePadUnion) == sizeof(Z) == 16
33 struct SimplePadNoPadding2
{
38 // No padding anywhere, sizeof(T) = 4
41 struct alignas(4) SimplePadFields1
{
45 // 1 byte of padding here, sizeof(T) = 4
48 struct SimplePadFields2
{
53 struct SimplePadBase
{
54 // Make sure this class is 4 bytes, and the derived class requires 8 byte
55 // alignment, so that padding is inserted between base and derived.
60 struct SimplePadDerived
: public SimplePadBase
{
61 // 4 bytes of padding here due to Y requiring 8 byte alignment.
62 // Thus, sizeof(T) = 16
66 struct SimplePadEmptyBase1
{};
67 struct SimplePadEmptyBase2
{};
69 struct SimplePadEmpty
: public SimplePadEmptyBase1
, SimplePadEmptyBase2
{
70 // Bases have to occupy at least 1 byte of storage, so this requires
71 // 2 bytes of padding, plus 1 byte for each base, yielding sizeof(T) = 8
75 struct SimplePadVfptr
{
76 virtual ~SimplePadVfptr() {}
77 static void operator delete(void *ptr
, size_t sz
) {}
81 struct NonEmptyBase1
{
85 struct NonEmptyBase2
{
89 struct SimplePadMultiInherit
: public NonEmptyBase1
, public NonEmptyBase2
{
90 // X and Y from the 2 bases will get squished together, leaving 2 bytes
91 // of padding necessary for proper alignment of an int32.
92 // Therefore, sizeof(T) = 2 + 2 + 4 = 8
96 struct SimplePadMultiInherit2
: public SimplePadFields1
, SimplePadFields2
{
97 // There should be 1 byte of padding after the first class, and
98 // 3 bytes of padding after the second class.
102 struct OneLevelInherit
: public NonEmptyBase1
{
106 struct SimplePadTwoLevelInherit
: public OneLevelInherit
{
107 // OneLevelInherit has nested padding because of its base,
108 // and then padding again because of this class. So each
109 // class should be 4 bytes, yielding sizeof(T) = 12.
113 struct SimplePadAggregate
{
116 // the presence of X will cause 3 bytes of padding to be injected.
117 SimplePadFields1 Fields
;
120 struct SimplePadVtable1
{
121 static void operator delete(void *ptr
, size_t sz
) {}
122 virtual ~SimplePadVtable1() {}
127 struct SimplePadVtable2
{
128 static void operator delete(void *ptr
, size_t sz
) {}
129 virtual ~SimplePadVtable2() {}
135 struct 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() {}
144 struct SimplePadMultiVTables
145 : public SimplePadVtable1
,
146 public SimplePadVtable2
,
147 public SimplePadVtable3
{
149 ~SimplePadMultiVTables() override
{}
150 static void operator delete(void *ptr
, size_t sz
) {}
152 // SimplePadVtable1 overrides
153 void A1() override
{}
155 // SimplePadVtable2 overrides
156 void Y2() override
{}
157 void Z2() override
{}
159 // SimplePadVtable3 overrides
160 void Bar3() override
{}
161 void Baz3() override
{}
162 void Buzz3() override
{}
165 int main(int argc
, char **argv
) {