§6.7.2.1 Structure and union specifiers, paragraph 3, specifies the following constraint:
A structure or union shall not contain a member with incomplete or function type [...], 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.
As a result, while the definition of union U in the following snippet is valid, the definition of the equivalent struct S is not and must be diagnosed by a conforming implementation.
struct X { int i, a[]; }; union U { struct X x1; // valid }; struct S { struct X x2; // constraint violation };
We believe this restriction is undesirable and possibly unintended. It is perfectly safe to accept the defition of struct S, or for that matter any other struct containing struct X just as long as struct X is the last subobject (possibly recursively) of the enclosing object. Such definitions are accepted by most popular compilers with just a strict conformance warning.
To reflect wide-spread existing practice, we propose the standard be changed and the constraint on structures with flexible array members relaxed to allow other structures to contain members of such structures provided the flexible array is the last (possibly nested) member of an object of the enclosing structure.
The intent is to make strictly conforming not only the definition of struct S below but also struct S2, but not that of struct S3.
struct X { int i, a[]; }; struct S { struct X x2; // proposed to be valid }; struct S2 { struct S s; // proposed to be valid }; struct S3 { struct X s; // constraint violation int last; };
The definitions of the proposed-to-be-valid structs are already accepted by known implementations with just a (pedantic) warning, as an extension.
To this effect we propose to change §6.7.2.1 Structure and union specifiers, paragraph 3, as indicated below:
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 bea member of a structure oran element of an array, or (possibly recursively) a member of another structure unless it is the last member of the enclosing structure.