Possible Duplicate:
Flexible array members in C - bad?
I read the following code:
struct hello {
int number;
int data[1];
};
I know the Flexible array members allow we can declare the last element to be an array of unspecified size
like this:
struct hello {
int number;
int data[];
};
In this struct
, the last element does not specify the size, so what is the difference between these two? and what does the first declaration mean?
This kind of array:
struct hello {
int number;
int data[];
};
only makes sense as last element of struct, and only when you allocate struct from heap, and typically so that header fields contain the real size of the array:
struct hello *helloptr = malloc(sizeof (struct hello) + count*(sizeof int));
helloptr->number = count;
The use is to allocate header and data buffer conveniently with one struct.
Addition: The difference to your version, which allocates array of size 1 is, sizeof struct hello
will be more, since array is allocated with one element instead undefined=zero. This either wastes one item worth of memory, or makes size calculations more complex, and is a bit "ugly" conceptually (your code has size 1 array, when you actually mean "undefined", possibly even 0).
In OOP C++ it's better to just wrap dynamically allocated buffer inside a class, this is kind of a "hack" really.
It is not a flexible array member but is used in some code that needs to work with old compilers or with c++ compilers.
Using it as a flexible array member might provoke undefined behavior. In real code this should work as expected as this trick is used in too much code for the compiler to make any unexpected things.
What is the difference between data[1]
and data[0]
?
Difference is none, both can be used for implementing flexible sized structure.
Raymond Chen answers it aptly:
Okay, you may say, then why not use a zero-length array instead of a 1-length array?
Because time travel has yet to be perfected.
Zero-length arrays did not become legal Standard C until 1999. Since Windows was around long before then, it could not take advantage of that functionality in the C language.
Note that technically, both the second code example is not valid C++ code.[Ref 1] But lot of existing code uses this functionality and this code will almost work always.
[Ref 1]Reference:
C++11 Standard: 8.3.4 Arrays
In a declaration T
D
where D
has the form
D1 [ constant-expressionopt] attribute-specifier-seqopt
.......
If the constant-expression (5.19) is present, it shall be an integral constant expression and its value shall be greater than zero.
Both are not completely equivalent in C, even if you only access the first element. A flexible array can have different alignment than the fixed size array would have. So even sizeof
could give you different results for both and you should never mix these two variants inside the same code.