3 ms·
I think you made a small mistake: an "incomplete array type", as allowed by the clause you cited, is one with empty brackets (int foo[]). Per 6.7.5.2.4: > If t
by comex 11y ago
I think you made a small mistake: an "incomplete array type", as allowed by the clause you cited, is one with empty brackets (int foo[]). Per 6.7.5.2.4:
> If the size is not present, the array type is an incomplete type.
This is different from specifying the size as 0, which is still not allowed, per 6.7.5.2.1:
> In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero.
Oh, and for the record, while you may be alluding to this in your last paragraph: another advantage of flexible array members is that indexing them is actually well-defined per the spec (if enough space has been allocated, of course), while AFAIK the spec has never added a special case for length-1 arrays, so accessing the "extra elements" is technically undefined behavior. However, common compilers like GCC do treat length 1 specially, as an exception to optimizations that generally assume you won't index out of bounds, so 'technically' really is 'technically' - it's not something that some random future version of GCC is likely to break your code if you use.
- caf 11y agoThis is right - a flexible array member is denoted with []. If you update the OPs example to try and put two of them in, you get this error from GCC: x.c:7:10: error: flexible array member not at end of struct
- kazinator 11y agoEven though I got the quote right out of C99, I still mixed it up. The reason for this is that ... I don't use flexible array member myself or the [0] GCC extension, either. Flexible array member doesn't seem to bring anything to the table other than formal definedness of behavior. I can't imagine any implementation which supports flexible-array member in its C99+ modes, which makes [1] fail in the same modes or in the C99 mode. In any old compiler that doesn't have C99 support, that formally undefined struct hack is all you have. I don't mind using offsetof(type, member) to obtain the size of the header before the array, rather than sizeof(type). The classic hack is portable to C90 and C++98, making it good for "Clean C". That said, flexible array member is elegant in the sense that it just uses an incomplete array type similarly to a file scope array declaration. Using [1] is a bit like while (1) instead of for (;;). I don't like the [1] in the struct hack, but I don't use C for its beauty.