2

What is the advantage of using zero-length arrays in C?

Eg:

struct email {
    time_t send_date;
    int flags;
    int length;
    char body[];
}list[0];
djadmin
  • 1,742
  • 3
  • 19
  • 27

2 Answers2

4

An array of size 0 is not valid in C.

char bla[0];  // invalid C code

From the Standard:

(C99, 6.7.5.2p1) "If the expression is a constant expression, it shall have a value greater than zero."

So list declaration is not valid in your program.

An array with an incomplete type as the last member of a structure is a flexible array member.

struct email {
    time_t send_date;
    int flags;
    int length;
    char body[];
};

Here body is a flexible array member.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • True, but most compilers allowed you to get away with it, and it was commonly done before the flexible array member was codified. And yeah, people should have written body[1] when using the [struct hack](http://stackoverflow.com/questions/3711233/is-the-struct-hack-technically-undefined-behavior), but they didn't always. Such code should be pretty rare these days, so you may encounter it in the wild. – dmckee --- ex-moderator kitten Sep 13 '12 at 18:16
  • @dmckee Didn't they only let you get away with it as the last member of a struct, not as a freestanding array of length 0? – Daniel Fischer Sep 13 '12 at 18:18
  • @DanielFischer Depended on the compiler. Some just let it slide so that they didn't have to special case the array hack. – dmckee --- ex-moderator kitten Sep 13 '12 at 18:19
  • @DanielFischer: There are a number of situations where being able to define a size-zero array and have it represent a pointer to the spot where the next struct element would go, would be useful. Many wouldn't require any special handling on the part of a typical compiler, beyond simply removing the code that triggers a compiler error on a zero-length array. Why should the compiler writer go out of his way to forbid something that could be useful? The only disadvantage I could see for allowing the construct would be that code like: – supercat Dec 05 '12 at 16:57
  • @DanielFischer: `struct {unsigned char a; unsigned char NumAsBytes[0]; unsigned int num;}` might not completely overlay `NumAsBytes` on `num`; to make it work properly, one would have to add an `int dummy[0]` before the `NumAsByte[0]` declaration to force the start of the array to be word aligned. – supercat Dec 05 '12 at 16:58
  • @supercat Can you give an example of a situation where it would be useful? I can't come up with one right now. – Daniel Fischer Dec 05 '12 at 17:05
  • @DanielFischer: Flexible array members would be the biggest use, but in some cases it can be useful to force something to be aligned more strictly than its type would suggest. For example, on some implementations, memcpy() can run more than twice as fast when source and destination are word aligned, than when one is and the other isn't. Putting a zero-length array of a type requiring coarser alignment before the thing to be aligned is a way to force such alignment, on compilers that allow such things. – supercat Dec 05 '12 at 17:21
  • @supercat I don't understand what you mean with "Flexible array members would be the biggest use", did you mean inserting a zero-length array before a flexible array member for alignment? That would make sense. To align other stuff, you can use (anonymous, inside structs) unions, I'm not sure zero-length arrays would be a win there (might be, don't know). – Daniel Fischer Dec 05 '12 at 18:21
  • @DanielFischer: Many compilers used to allow zero-length arrays; the biggest use of such arrays was as a means of implementing flexible array members before the present syntax became legal. While anonymous union members provide nice ways of aligning and/or overlaying things within structures, on older compilers (like the ones that allowed zero-length arrays) using unions to force alignment or overlay things would compel code that used the struct to add an icky extra level of nesting (e.g. `mystruct.header.length` rather than `mystruct.length`). – supercat Dec 05 '12 at 18:41
  • @supercat Ah, you meant for compilers that don't support flexible array members and anonymous unions. Yes, _then_ I see the usefulness. – Daniel Fischer Dec 05 '12 at 18:46
  • @DanielFischer: Sorry I was unclear. One of my peeves with the C standards has been that they forbade a construct which was useful (zero-length arrays) before any equally-convenient alternative existed. Further, I should mention that there's still a case where a zero-element array would be useful: code where the size of an array may depend upon configuration options, and where the options may result in the size being zero (e.g. `struct foo {WHOLEBLOCK blocks [DATA_MAX/256]; extra[DATA_MAX & 255];`} where DATA_MAX could be less than 256, or a multiple of 256. – supercat Dec 05 '12 at 18:53
-1

Here is your answer: http://www.quora.com/C-programming-language/What-is-the-advantage-of-using-zero-length-arrays-in-C

Kiran
  • 5,478
  • 13
  • 56
  • 84