gcc: Zero Length

1 
1 6.17 Arrays of Length Zero
1 ==========================
1 
1 Zero-length arrays are allowed in GNU C.  They are very useful as the
1 last element of a structure that is really a header for a
1 variable-length object:
1 
1      struct line {
1        int length;
1        char contents[0];
1      };
1 
1      struct line *thisline = (struct line *)
1        malloc (sizeof (struct line) + this_length);
1      thisline->length = this_length;
1 
1  In ISO C90, you would have to give 'contents' a length of 1, which
1 means either you waste space or complicate the argument to 'malloc'.
1 
1  In ISO C99, you would use a "flexible array member", which is slightly
1 different in syntax and semantics:
1 
1    * Flexible array members are written as 'contents[]' without the '0'.
1 
1    * Flexible array members have incomplete type, and so the 'sizeof'
1      operator may not be applied.  As a quirk of the original
1      implementation of zero-length arrays, 'sizeof' evaluates to zero.
1 
1    * Flexible array members may only appear as the last member of a
1      'struct' that is otherwise non-empty.
1 
1    * A structure containing a flexible array member, or a union
1      containing such a structure (possibly recursively), may not be a
1      member of a structure or an element of an array.  (However, these
1      uses are permitted by GCC as extensions.)
1 
1  Non-empty initialization of zero-length arrays is treated like any case
1 where there are more initializer elements than the array holds, in that
1 a suitable warning about "excess elements in array" is given, and the
1 excess elements (all of them, in this case) are ignored.
1 
1  GCC allows static initialization of flexible array members.  This is
1 equivalent to defining a new structure containing the original structure
1 followed by an array of sufficient size to contain the data.  E.g. in
1 the following, 'f1' is constructed as if it were declared like 'f2'.
1 
1      struct f1 {
1        int x; int y[];
1      } f1 = { 1, { 2, 3, 4 } };
1 
1      struct f2 {
1        struct f1 f1; int data[3];
1      } f2 = { { 1 }, { 2, 3, 4 } };
1 
1 The convenience of this extension is that 'f1' has the desired type,
1 eliminating the need to consistently refer to 'f2.f1'.
1 
1  This has symmetry with normal static arrays, in that an array of
1 unknown size is also written with '[]'.
1 
1  Of course, this extension only makes sense if the extra data comes at
1 the end of a top-level object, as otherwise we would be overwriting data
1 at subsequent offsets.  To avoid undue complication and confusion with
1 initialization of deeply nested arrays, we simply disallow any non-empty
1 initialization except when the structure is the top-level object.  For
1 example:
1 
1      struct foo { int x; int y[]; };
1      struct bar { struct foo z; };
1 
1      struct foo a = { 1, { 2, 3, 4 } };        // Valid.
1      struct bar b = { { 1, { 2, 3, 4 } } };    // Invalid.
1      struct bar c = { { 1, { } } };            // Valid.
1      struct foo d[1] = { { 1, { 2, 3, 4 } } };  // Invalid.
1