Following the brief discussion Re: aliasing between internal zero-length-arrays and other members(*) the attached patch updates the documentation of Zero-length arrays to clarify that the only valid accesses are to those where the array is the last member of a struct.
I also took the liberty to mention a couple of more details that may be of interest to users: namely their alignment and size, and the handling of one-element arrays. As I mentioned in the strnlen patch I just submitted, I'd like to add support for detecting the misuses of zero-length arrays but I thought I'd post this one first to help flesh out the implementation of the warning. Martin [*] https://gcc.gnu.org/ml/gcc/2018-06/msg00046.html
gcc/ChangeLog: * doc/extend.texi (Zero-length arrays): Update and clarify. Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 261207) +++ gcc/doc/extend.texi (working copy) @@ -1538,9 +1538,9 @@ defined when these address spaces are supported. @cindex length-zero arrays @cindex flexible array members -Zero-length arrays are allowed in GNU C@. They are very useful as the -last element of a structure that is really a header for a variable-length -object: +Declaring zero-length arrays is allowed in GNU C as an extension@. +A zero-length array can be useful as the last element of a structure +that is really a header for a variable-length object: @smallexample struct line @{ @@ -1553,12 +1553,28 @@ struct line *thisline = (struct line *) thisline->length = this_length; @end smallexample -In ISO C90, you would have to give @code{contents} a length of 1, which -means either you waste space or complicate the argument to @code{malloc}. +Although the size of a zero-length array is zero, an array member of +this kind may increase the size the enclosing type as a result of tail +padding. The offset of a zero-length array member from the beginning +of the enclosing structure is the same as the offset of an array with +one or more elements of the same type. The alignment of a zero-length +array is the same as the alignment of its elements. -In ISO C99, you would use a @dfn{flexible array member}, which is -slightly different in syntax and semantics: +Declaring zero-length arrays in other contexts, including as interior +members of structure objects or as non-member objects is discouraged. +Accessing elements of zero-length arrays declared in such contexts is +undefined and may be diagnosed. +In the absence of the zero-length array extension, in ISO C90 the +@code{contents} array in the example above would typically be declared +to have a single element. Although this technique is discouraged, GCC +handles trailing one-element array members similarly to zero-length +arrays. + +The preferred mechanism to declare variable-length types like +@code{struct line} above is the ISO C99 @dfn{flexible array member}, +with slightly different in syntax and semantics: + @itemize @bullet @item Flexible array members are written as @code{contents[]} without