3

C11, 6.7.2.1 Structure and union specifiers, Constraints, 3 (emphasis added):

A structure or union shall not contain a member with incomplete or function type (hence, a structure shall not contain an instance of itself, but may contain a pointer to an instance of itself), except that the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.

Rationale for C, Revision 5.10, April-2003 (emphasis added):

Similarly, structures containing flexible arrays can’t occur in other structures or in arrays.

So, Rationale for C doesn't provide a rationale. What is the rationale?

TylerH
  • 20,799
  • 66
  • 75
  • 101
pmor
  • 5,392
  • 4
  • 17
  • 36

1 Answers1

4

A structure with a flexible array member can only really be used properly if allocated dynamically. For example:

struct s1 {
    int a;
    int b;
    int c[];
};
...
struct s1 *x = malloc(sizeof(struct s1) + 5 * sizeof(int));

Let's assume typical struct padding and sizeof(int)==4. That would make sizeof(struct s1)==8.

Now imagine if such a struct was a member of another struct:

struct s2 {
    int a;
    struct s1 b;
    int c;
};

The b member of struct s2 would start at offset 4. But what about the c member? Given that sizeof(struct s1)==8, that would make member c have offset 12. But then there's no way for the b member to have any space set aside for its containing c member.

Because the offset of a given struct member is set at compile time, there is no way to allocate space for the flexible array member c inside of struct s1.

In theory, if the struct with a flexible array member was the last member:

struct s2 {
    int a;
    int b;
    struct s1 c;
};

Then it could work, but then then means that struct s2 is also subject to the same rules as a struct with a flexible array member, causing a cascading effect. This would make it more difficult to determine which structures are subject to this rule.

So a struct with a flexible array member is not allowed as a member of another struct or an array.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 2
    This does not explain why the rule for structures with flexible array members would not simply be the same as the rule for flexible array members: They must be last. – Eric Postpischil Feb 07 '22 at 14:20
  • @EricPostpischil Can you elaborate? Which rule exactly? – pmor Feb 15 '22 at 21:36
  • @pmor: Your question asks about the rule that a structure with a flexible array member “shall not be a member of a structure.” That rule could be “shall not be a member of a structure other than the last member.” This answer does not give any reason against that. – Eric Postpischil Feb 15 '22 at 21:40
  • @EricPostpischil Indeed! Logically it can be the last member. (The similar case is "There is only one name space for tags even though three are possible". Then why not making three? Rationale doesn't answer that.) – pmor Feb 16 '22 at 00:09