346-c11-decl-align.c (2706B)
1 /* Small C11 declaration forms used by Kit's public/core headers. _Alignas 2 * is intentionally natural here: cc.scm's seed ABI accepts the spelling but 3 * does not promise over-aligned storage. */ 4 5 typedef struct Pair { 6 char c; 7 long value; 8 _Static_assert(sizeof(long) >= sizeof(char), "member assertion"); 9 } Pair; 10 11 struct Nested { 12 struct { 13 int value; 14 } inner; 15 }; 16 17 typedef struct Slice { 18 const char *text; 19 unsigned long len; 20 } Slice; 21 22 typedef struct NameSlice { 23 union { 24 const char *s; 25 const unsigned char *data; 26 }; 27 unsigned long len; 28 } NameSlice; 29 30 typedef struct InsnDesc { 31 NameSlice name; 32 int code; 33 } InsnDesc; 34 35 #define SLICE(lit) ((Slice){ .text = (lit), .len = sizeof(lit) - 1 }) 36 #define NAME_SLICE(lit) \ 37 ((NameSlice){ .s = (lit), .len = sizeof(lit) - 1 }) 38 39 _Static_assert(_Alignof(long) == sizeof(long), "natural scalar alignment"); 40 _Static_assert(_Alignof(Pair) >= _Alignof(long), "aggregate alignment"); 41 42 _Alignas(char) static long aligned_value = 9; 43 static const unsigned seed_table[] = { 1, 2, 3 }; 44 static const unsigned designated_table[4] = { [2] = 13, [0] = 5 }; 45 static const struct Nested nested = { .inner.value = 11 }; 46 static const Slice slices[] = { SLICE("x"), SLICE("yz") }; 47 static const InsnDesc insns[] = { 48 {{{("movn")}, sizeof("movn") - 1}, 3}, 49 }; 50 static const InsnDesc compound_insns[] = { 51 {NAME_SLICE("movz"), 4}, 52 }; 53 54 _Static_assert(sizeof seed_table / sizeof seed_table[0] == 3, 55 "file-scope unevaluated array designator"); 56 _Static_assert(_Alignof(seed_table[0]) == _Alignof(unsigned), 57 "file-scope alignof expression"); 58 _Static_assert(__alignof__(unsigned) == _Alignof(unsigned), 59 "GNU alignof alias"); 60 _Static_assert(__builtin_offsetof(Pair, value) == _Alignof(long), 61 "builtin offsetof uses aggregate layout"); 62 _Static_assert(sizeof(((Pair *)0)->value) == sizeof(long), 63 "file-scope sizeof handles a cast designator"); 64 65 _Noreturn static void seed_noreturn_spelling(int *out) 66 { 67 *out = 7; 68 } 69 70 int main(void) 71 { 72 int result = 0; 73 _Static_assert(_Alignof(Pair) >= 1, "block assertion"); 74 seed_noreturn_spelling(&result); 75 return result + (aligned_value != 9) + (nested.inner.value != 11) + 76 (slices[0].len != 1) + (slices[1].text[0] != 'y') + 77 (designated_table[0] != 5) + (designated_table[1] != 0) + 78 (designated_table[2] != 13) + (designated_table[3] != 0) + 79 (insns[0].name.s[0] != 'm') + (insns[0].code != 3) + 80 (compound_insns[0].name.s[3] != 'z') + 81 (compound_insns[0].code != 4) + 82 (__builtin_offsetof(Pair, value) != _Alignof(long)); 83 }