boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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 }