Copyright (C) 2000-2012 |
GNU Info (gcc-300.info)Zero LengthArrays of Length Zero ===================== Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure which is really a header for a variable-length object: struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length; In ISO C89, you would have to give `contents' a length of 1, which means either you waste space or complicate the argument to `malloc'. In ISO C99, you would use a "flexible array member", which is slightly different in syntax and semantics: * Flexible array members are written as `contents[]' without the `0'. * Flexible array members have incomplete type, and so the `sizeof' operator may not be applied. As a quirk of the original implementation of zero-length arrays, `sizeof' evaluates to zero. * Flexible array members may only appear as the last member of a `struct' that is otherwise non-empty. GCC currently allows zero-length arrays anywhere. You may encounter problems, however, defining structures containing only a zero-length array. Such usage is deprecated, and we recommend using zero-length arrays only in places in which flexible array members would be allowed. GCC versions before 3.0 allowed zero-length arrays to be statically initialized. In addition to those cases that were useful, it also allowed initializations in situations that would corrupt later data. Non-empty initialization of zero-length arrays is now deprecated. Instead GCC allows static initialization of flexible array members. This is equivalent to defining a new structure containing the original structure followed by an array of sufficient size to contain the data. I.e. in the following, `f1' is constructed as if it were declared like `f2'. struct f1 { int x; int y[]; } f1 = { 1, { 2, 3, 4 } }; struct f2 { struct f1 f1; int data[3]; } f2 = { { 1 }, { 2, 3, 4 } }; The convenience of this extension is that `f1' has the desired type, eliminating the need to consistently refer to `f2.f1'. This has symmetry with normal static arrays, in that an array of unknown size is also written with `[]'. Of course, this extension only makes sense if the extra data comes at the end of a top-level object, as otherwise we would be overwriting data at subsequent offsets. To avoid undue complication and confusion with initialization of deeply nested arrays, we simply disallow any non-empty initialization except when the structure is the top-level object. For example: struct foo { int x; int y[]; }; struct bar { struct foo z; }; struct foo a = { 1, { 2, 3, 4 } }; // Valid. struct bar b = { { 1, { 2, 3, 4 } } }; // Invalid. struct bar c = { { 1, { } } }; // Valid. struct foo d[1] = { { 1 { 2, 3, 4 } } }; // Invalid. automatically generated by info2www version 1.2.2.9 |