<story><title>Zero size arrays in C</title><url>http://www.labbott.name/blog/2016/05/10/zero-size-arrays-in-c</url></story><parent_chain></parent_chain><comment><author>kazinator</author><text>A zero sized array declaration was a constraint violation (this requiring a diagnostic) in ISO C 90 in all contexts: even as a function parameter, where the identifier being declared is actually a pointer and not an array at all!&lt;p&gt;C99 added the &amp;quot;flexible array member&amp;quot; feature: the last element of a struct can be an array of size zero: &amp;quot;As a special case, the last element of a structure with more than one named member may
have an incomplete array type; this is called a &lt;i&gt;flexible array member&lt;/i&gt;.&amp;quot; [C99, 6.7.2.1 ¶16]&lt;p&gt;In C90 code, the &amp;quot;struct hack&amp;quot; is implemented using an array of size [1] at the end of a struct. Some compilers allowed zero (like GNU C, I think) before C99.&lt;p&gt;In any case, supporting a [0]-sized array member which is not the last member of a struct, without issuing a diagnostic, is non-conforming.  The example given in the article with consecutive [0] arrays requires a diagnostic.&lt;p&gt;By the way, the (apparently only?) advantage of the flexible array member is that we can use sizeof (type) to obtain the size of the structure just excluding the first element of the array. Whereas with the C90 style struct hack, we must use offsetof(type, last_member) so that we exclude [1] from the calculation:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  struct foo {
    &amp;#x2F;* ... *&amp;#x2F;
    int array[ZERO_OR_ONE];
  };

  &amp;#x2F;* Correct in C99, if ZERO_OR_ONE is 0
     Incorrect in C90, (ZERO_OR_ONE can&amp;#x27;t be zero).  *&amp;#x2F;
  size_t foo_plus_3_elems = sizeof (struct foo) + 3 * sizeof(int);

  &amp;#x2F;* Correct in C99 whether or not ZERO_OR_ONE is 0 or 1.
     Correct in C90 with ZERO_OR_ONE being 1. *&amp;#x2F;
  size_t foo_plus_3_elems = offsetof (struct foo, array) + 3 * sizeof(int);
&lt;/code&gt;&lt;/pre&gt;
Here, &amp;quot;incorrect&amp;quot; means we calculate slightly more storage than needed, usually without any downside.&lt;p&gt;&amp;quot;Correct in C90&amp;quot; means &lt;i&gt;de facto&lt;/i&gt; correct, not that it was well-defined behavior. &amp;quot;Everyone&amp;quot; was doing it.</text></comment>
<story><title>Zero size arrays in C</title><url>http://www.labbott.name/blog/2016/05/10/zero-size-arrays-in-c</url></story><parent_chain></parent_chain><comment><author>jandrese</author><text>That seemed pretty straightforward to me.  A zero size array is better thought of as a pointer to that part of the struct, and if you put two back to back you get two pointers to the same spot.  I&amp;#x27;m not sure what that guy was expecting to happen.&lt;p&gt;The usual reason to use them is when you have a protocol header with a variable length data portion.  Putting the zero length array in the struct allows you easy access to the data while not changing the sizeof() the header so you can avoid a bit of pesky pointer math and make the code easier to read.&lt;p&gt;Thinking about this some more, you could also use this as a ghetto form of union, but I&amp;#x27;m not sure why you would want to.&lt;p&gt;&lt;pre&gt;&lt;code&gt;  struct
  {
    char[0] theBytes;
    int     theValue;
  }&lt;/code&gt;&lt;/pre&gt;</text></comment>