cstructlanguage-lawyerflexible-array-member

What is the rationale for "structure with flexible array member shall not be a member of a structure"?


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?


Solution

  • 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.