6.7.2.3 Tags
Constraints
A specific type shall have its content defined at most once.
Where two declarations that use the same tag declare the same type, they shall both use the same choice of struct, union, or enum.
A type specifier of the form
enum identifier
without an enumerator list shall only appear after the type it specifies is complete.
Semantics
All declarations of structure, union, or enumerated types that have the same scope and use the same tag declare the same type. The type is incomplete[1] until the closing brace of the list defining the content, and complete thereafter.
Two declarations of structure, union, or enumerated types which are in different scopes or use different tags declare distinct types. Each declaration of a structure, union, or enumerated type which does not include a tag declares a distinct type.
A type specifier of the form
struct-or-union identifieropt { struct-declaration-list }
or
enum identifier { enumerator-list }
or
enum identifier { enumerator-list , }
declares a structure, union, or enumerated type. The list defines the structure content, union content, or enumeration content. If an identifier is provided,[2] the type specifier also declares the identifier to be the tag of that type.
A declaration of the form
struct-or-union identifier ;
specifies a structure or union type and declares the identifier as a tag of that type.[3]
If a type specifier of the form
struct-or-union identifier
occurs other than as part of one of the above forms, and no other declaration of the identifier as a tag is visible, then it declares an incomplete structure or union type, and declares the identifier as the tag of that type.[3]
If a type specifier of the form
struct-or-union identifier
or
enum identifier
occurs other than as part of one of the above forms, and a declaration of the identifier as a tag is visible, then it specifies the same type as that other declaration, and does not redeclare the tag.
EXAMPLE 1
This mechanism allows declaration of a self-referential structure.
struct tnode {
int count;
struct tnode *left, *right;
};
specifies a structure that contains an integer and two pointers to objects of the same type. Once this declaration has been given, the declaration
struct tnode s, *sp;
declares s to be an object of the given type and sp to be a pointer to an object of the given type. With these declarations, the expression sp->left refers to the left struct tnode pointer of the object to which sp points; the expression s.right->count designates the count member of the right struct tnode pointed to from s.
The following alternative formulation uses the typedef mechanism:
typedef struct tnode TNODE;
struct tnode {
int count;
TNODE *left, *right;
};
TNODE s, *sp;
EXAMPLE 2
To illustrate the use of prior declaration of a tag to specify a pair of mutually referential structures, the declarations
struct s1 { struct s2 *s2p; /* ... */ }; // D1
struct s2 { struct s1 *s1p; /* ... */ }; // D2
specify a pair of structures that contain pointers to each other. Note, however, that if s2 were already declared as a tag in an enclosing scope, the declaration D1 would refer to it, not to the tag s2 declared in D2. To eliminate this context sensitivity, the declaration
struct s2;
may be inserted ahead of D1. This declares a new tag s2 in the inner scope; the declaration D2 then completes the specification of the new type.
Forward References
Footnotes