117-compound-literal.c (3362B)
1 /* Compound literals (C99 §6.5.2.5): `(T){ init-list }` as a postfix 2 * expression. Scope: block-scope only. Initializer grammar reuses the 3 * existing local-aggregate path (positional, designated, trailing 4 * commas, partial-init zero-fill). 5 * 6 * A compound literal is an lvalue with automatic storage tied to the 7 * enclosing block, so it can be addressed, indexed, member-accessed, 8 * and passed to functions whose parameters expect a pointer. 9 */ 10 11 struct Point { int x; int y; }; 12 13 int sum_pt(struct Point p) { return p.x + p.y; } 14 int sum_pt_ptr(struct Point *p) { return p->x + p->y; } 15 int sum_arr3(int *a) { return a[0] + a[1] + a[2]; } 16 17 int test_scalar(void) { 18 int v = (int){42}; 19 if (v != 42) return 1; 20 return 0; 21 } 22 23 int test_array_index(void) { 24 /* Direct index on the literal — array decays to pointer. */ 25 if ((int[]){10, 20, 30}[1] != 20) return 1; 26 if ((int[3]){5, 6, 7}[2] != 7) return 2; 27 return 0; 28 } 29 30 int test_array_decay(void) { 31 /* Bound to a pointer; outlives current full-expression because 32 * compound literals at block scope live until the block ends. */ 33 int *p = (int[]){100, 200, 300}; 34 if (p[0] + p[1] + p[2] != 600) return 1; 35 return 0; 36 } 37 38 int test_array_as_arg(void) { 39 return sum_arr3((int[]){1, 2, 4}) == 7 ? 0 : 1; 40 } 41 42 int test_struct_positional(void) { 43 struct Point q = (struct Point){3, 4}; 44 if (q.x != 3) return 1; 45 if (q.y != 4) return 2; 46 return 0; 47 } 48 49 int test_struct_designated(void) { 50 struct Point q = (struct Point){.y = 5, .x = 7}; 51 if (q.x != 7) return 1; 52 if (q.y != 5) return 2; 53 /* Partial designated init: unmentioned field is zeroed. */ 54 struct Point r = (struct Point){.x = 9}; 55 if (r.x != 9) return 3; 56 if (r.y != 0) return 4; 57 return 0; 58 } 59 60 int test_struct_as_arg_byval(void) { 61 return sum_pt((struct Point){10, 20}) == 30 ? 0 : 1; 62 } 63 64 int test_struct_addr(void) { 65 /* &literal — compound literals are lvalues. */ 66 return sum_pt_ptr(&(struct Point){11, 22}) == 33 ? 0 : 1; 67 } 68 69 int test_struct_member_direct(void) { 70 /* Member access directly on the literal. */ 71 if ((struct Point){50, 60}.x != 50) return 1; 72 if ((struct Point){50, 60}.y != 60) return 2; 73 return 0; 74 } 75 76 int test_trailing_comma(void) { 77 int *p = (int[]){1, 2, 3,}; 78 return (p[0] + p[1] + p[2]) == 6 ? 0 : 1; 79 } 80 81 int test_partial_array(void) { 82 /* Trailing zeros for unspecified elements. */ 83 int *p = (int[5]){1, 2}; 84 if (p[0] != 1) return 1; 85 if (p[1] != 2) return 2; 86 if (p[2] != 0) return 3; 87 if (p[3] != 0) return 4; 88 if (p[4] != 0) return 5; 89 return 0; 90 } 91 92 int main(int argc, char **argv) { 93 int r; 94 if ((r = test_scalar())) return 1 * 10 + r; 95 if ((r = test_array_index())) return 2 * 10 + r; 96 if ((r = test_array_decay())) return 3 * 10 + r; 97 if ((r = test_array_as_arg())) return 4 * 10 + r; 98 if ((r = test_struct_positional())) return 5 * 10 + r; 99 if ((r = test_struct_designated())) return 6 * 10 + r; 100 if ((r = test_struct_as_arg_byval()))return 7 * 10 + r; 101 if ((r = test_struct_addr())) return 8 * 10 + r; 102 if ((r = test_struct_member_direct()))return 9 * 10 + r; 103 if ((r = test_trailing_comma())) return 10 * 10 + r; 104 if ((r = test_partial_array())) return 11 * 10 + r; 105 return 0; 106 }