2.12 Tags

Tags can be used with structures, unions, or enumerated types as a means of referring to the structure, union, or enumerated type elsewhere in the program. Once a tag is included in the declaration of a structure, union, or enumerated type, it can specify the declared structure, union, or enumerated type anywhere the declaration is visible.

The following code fragment shows the use of a structure tag, a union tag, and an enumerated type tag:

struct tnode {                 /*  Initial declaration --             */
                               /*  tnode is the structure tag         */
 int count;
 struct tnode *left, *right;   /*  tnode's members referring to tnode */
 union datanode *p;            /*  forward reference to union type is
                                   declared below                     */
};

union datanode {               /*  Initial declaration --             */
                               /*  datanode is the union tag          */
 int ival;
 float fval;
 char *cval;
} q = {5};

enum color { red, blue, green };/*  Initial declaration --            */
.                               /*  color is the enumeration tag      */
.
.
struct tnode x;                /*   tnode tag is used to declare x    */
enum color z = blue;           /*   color tag declares z to be of
                                    type color;  z is also
                                    initialized to blue               */

As shown in the previous example, once a tag is declared it can be used to reference other structure, union, or enumerated type declarations in the same scope without fully redefining the object.

Tags can be used to form an incomplete type if they occur before the complete declaration of a structure or union. Incomplete types do not specify the size of the object; therefore, a tag introducing an incomplete type can only be used when the size of the object is not needed. To complete the type, another declaration of the tag in the same scope must define the object completely. The following example shows how a subsequent definition completes the incomplete declaration of the structure type s :

struct s;            /*  Tag s used in incomplete type declaration */
struct t {
  struct s *p;
};
struct s { int i; };/*  struct s definition completed              */

Section 2.6 describes the concept of an incomplete type.

Consider the following declarations:

struct tag;

union tag;

These declarations specify a structure or union type and declare a tag visible only within the scope of the declaration. The declaration specifies a new type distinct from any other type with the same tag in an enclosing scope (if any).

The following example shows the use of prior tag declarations to specify a pair of mutually-referential structures:

struct s1 { struct s2 *s2p; /*...*/ };  /* D1  */
struct s2 { struct s1 *s1p; /*...*/ };  /* D2  */

If s2 was declared as a tag in an enclosing scope, the declaration D1 would refer to s2 , not to the tag s2 declared in D2 . To eliminate this context sensitivity, the following declaration can be inserted ahead of D1 :

struct s2;

This declares a new tag s2 in the inner scope; the declaration D2 then completes the specification of the type.


Previous Page | Next Page | Table of Contents | Index