opt_06_flexible_array_element_address.c (1093B)
1 /* Taking the address of an element in a flexible array carries the unsized 2 * array lvalue through IR_ADDR_OF. It computes an address and does not access 3 * the incomplete array object as a by-value storage operand. */ 4 typedef struct Segment { 5 int value; 6 } Segment; 7 8 typedef struct Iterator { 9 int count; 10 Segment segments[]; 11 } Iterator; 12 13 typedef struct Backing { 14 int count; 15 Segment segments[2]; 16 } Backing; 17 18 /* A union containing the flexible-array structure is allowed to provide the 19 * backing storage. Iterator and Backing have a compatible common initial 20 * sequence, so this exercises the flexible member without casting an 21 * unrelated declared object through Iterator (which would violate C11's 22 * effective-type rules). */ 23 typedef union Storage { 24 Iterator iterator; 25 Backing backing; 26 } Storage; 27 28 __attribute__((noinline)) static Segment* segment_at(Iterator* p, int i) { 29 return &p->segments[i]; 30 } 31 32 int test_main(void) { 33 Storage storage = {0}; 34 Segment* segment = segment_at(&storage.iterator, 1); 35 segment->value = 42; 36 return storage.backing.segments[1].value; 37 }