1 // PERMUTE_ARGS: 2 3 // MT!"y" is analyzed from the pragma inside MT!"x" 4 /* 5 TEST_OUTPUT: 6 --- 7 CT x.offsetof = < 8 CT y.offsetof = < 9 0 > y 10 0 > x 11 --- 12 */ 13 MT(string id)14mixin template MT(string id) 15 { 16 union 17 { 18 mixin("void* " ~ id ~ ";"); 19 } 20 21 // Evaluating `typeof(this).init` completes data layout. 22 pragma(msg, 23 "CT " ~ id ~ ".offsetof = <\n", 24 cast(int)typeof(this).init.i.offsetof, " > " ~ id); 25 } 26 27 struct S1 28 { 29 int i; 30 mixin MT!"x"; 31 mixin MT!"y"; 32 } 33 struct S2 34 { 35 int i; 36 union { void* x; } 37 union { void* y; } 38 } 39 struct S3 40 { 41 int i; 42 void* x; 43 void* y; 44 } 45 main()46void main() 47 { 48 // S1, S2, and S3 should have exactly same data layout. 49 static assert(S1.i.offsetof == S3.i.offsetof); 50 static assert(S1.i.offsetof == S3.i.offsetof); 51 static assert(S1.x.offsetof == S3.x.offsetof); 52 static assert(S1.y.offsetof == S3.y.offsetof); 53 static assert(S2.x.offsetof == S3.x.offsetof); 54 static assert(S2.y.offsetof == S3.y.offsetof); 55 static assert(S1.sizeof == S3.sizeof); 56 static assert(S2.sizeof == S3.sizeof); 57 58 S1 s = void; 59 60 s.i = 1; 61 assert(s.i == 1); 62 s.x = null; 63 assert(s.i == 1); 64 s.y = null; 65 assert(s.i == 1); 66 67 char a, b; 68 s.x = cast(void*)&a; 69 assert(s.x is &a); 70 assert(s.y is null); 71 s.y = cast(void*)&b; 72 assert(s.x is &a); 73 assert(s.y is &b); 74 } 75