There are some downsides related to how structs are sometimes used, and it can be dangerous if you don't think through the implications.
For your example, if you start a function:
void test(void) {
struct header;
char *p = &header.data[0];
...
}
Then the results are undefined (since no storage was ever allocated for data). This is something that you will normally be aware of, but there are cases where C programmers are likely used to being able to use value semantics for structs, which breaks down in various other ways.
For instance, if I define:
struct header2 {
int len;
char data[MAXLEN]; /* MAXLEN some appropriately large number */
}
Then I can copy two instances simply by assignment, i.e.:
struct header2 inst1 = inst2;
Or if they are defined as pointers:
struct header2 *inst1 = *inst2;
This however won't work for flexible array members, since their content is not copied over. What you want is to dynamically malloc the size of the struct and copy over the array with memcpy
or equivalent.
struct header3 {
int len;
char data[]; /* flexible array member */
}
Likewise, writing a function that accepts a struct header3
will not work, since arguments in function calls are, again, copied by value, and thus what you will get is likely only the first element of your flexible array member.
void not_good ( struct header3 ) ;
This does not make it a bad idea to use, but you do have to keep in mind to always dynamically allocate these structures and only pass them around as pointers.
void good ( struct header3 * ) ;