union (Unions)

A union is an object that can hold any one of a set of named members. The members of the named set can be of any data type. Members are overlaid in storage.

The storage allocated for a union is the storage required for the largest member of the union, plus any padding required for the union to end at a natural boundary of its strictest member.

In C++, a union can have member functions, including constructors and destructors, but not virtual member functions. A union cannot be used as a base class and cannot be derived from a base class.

A C++ union member cannot be a class object that has a constructor , destructor, or overloaded copy assignment operator. In C++, a member of a union cannot be declared with the keyword static.

Declaring a Union

identifier Provides a tag name for the union. If specified, subsequent declarations (in the same scope) of variables using the union can be made by referring to the tag name. If not specified, you must place all variable definitions that refer to the union within the declaration of the data type.
member The list of members provides the data type with a description of the values that can be stored in the union.

A member that does not represent a bit field can be of any data type and can have the volatile or const qualifier.

If a : (colon) and a constant expression follow the member declarator, the member represents a bit field. Bit fields are described in Declaring and Using Bit Fields in Structures.

You can reference one of the possible members of a union the same way as referencing a member of a structure.

For example:

union {
      char birthday[9];
      int age;
      float weight;
      } people;
 
people.birthday[0] = '\n';

assigns '\n' to the first element in the character array birthday, a member of the union people.

A union can represent only one of its members at a time. In the example, the union people contains either age, birthday, or weight but never more than one of these. The printf statement in the following example does not give the correct result because people.age replaces the value assigned to people.birthday in the first line:

1  people.birthday = "03/06/56";
2  people.age = 38;
3  printf("%s\n", people.birthday);

Defining a Union Variable
A union variable definition contains an optional storage class keyword, the union keyword, a union tag, and a declarator. The union tag indicates the data type of the union variable.

The type specifier contains the keyword union followed by the name of the union type. You must declare the union data type before you can define a union having that type.

You can define a union data type and a union of that type in the same statement by placing the variable declarator after the data type definition.

The declarator is an identifier, possibly with the volatile or const qualifier.

The initializer must be a constant expression if the union has static storage duration or if you are compiling your source code in ansi mode. If the union has auto storage duration, it can be initialized using the = (equal sign) followed by any expression that returns a compatible union value. You can only initialize the first member of a union.

The following example shows how you would initialize the first union member birthday of the union variable people:

union {
      char birthday[9];
      int age;
      float weight;
      } people = {"23/07/57"};

Defining a Union Type and a Union Variable
To define union type and a union variable in one statement, put a declarator after the type definition. The storage class specifier for the variable must go at the beginning of the statement.

Alignment of Unions
The rules for alignment of structures and structure members apply to unions, with the following exception: when the align=twobyte option is specified on AIX, a union whose largest element is a bit field of width 16 or less has a size of 2 bytes. If the width of the bit field is greater than 16, the size of the union is 4 bytes.

Anonymous Unions in C
Unions can be declared without declarators if they are members of another structure or union. Unions without declarators are called anonymous unions.

Note: Anonymous unions are not part of the the ANSI C language standard, and are supported by IBM C and C++ Compilers in extended compiler mode only.

Members of an anonymous union can be accessed as if they were declared directly in the containing structure or union. For example, given the following structure:

struct s {
   int a;
   union {
      int b;
      float c;
   };               /* no declarator */
} kurt;

you can make the following statements:

kurt.a = 5;
kurt.b = 36;

You can also declare an anonymous union by:

  1. Creating a typedef and using the typedef name without a declarator:
typedef union {
   int a;
   int b;
} UNION_T;

struct s1 {
   UNION_T;
   int c;
} dave;
  1. By using an existing union tag without a declarator:
union u1 {
   int a;
   int b;
};

struct s1 {
 union u1;
 int c;
} dave;

In both of these examples, the members can be accessed as dave.a, dave.b, and dave.c.

An anonymous union must be a member of, or nested within another anonymous union that is a member of, a named structure or union. If a union is declared at file scope without a declarator, its members are not available to the surrounding scope. For example, the following union only declares the union tag tom:

union tom {
   int b;
   float c;
} ;

The variables b and c from this union cannot be used at file scope, and the following statements will generate errors:

b = 5;
c = 2.5;

Anonymous Unions in C++
Anonymous unions are treated differently in the C++ language. Given these declarations:

union don {
   int a;
   int b;
};
struct pete {
   union don;
};

In C; "union don;" declares an anonymous union as a member of "pete". In C++, it is treated as a forward or incomplete declaration of a nested union, not as an anonymous union. A C++ anonymous union is a union without a class name. It cannot be followed by a declarator. An anonymous union is not a type; it defines an unnamed object and it cannot have member functions.

The member names of an anonymous union must be distinct from other names within the scope in which the union is declared. You can use member names directly in the union scope without any additional member access syntax.

For example, in the following code fragment, you can access the data members i and cptr directly because they are in the scope containing the anonymous union. Because i and cptr are union members and have the same address, you should only use one of them at a time. The assignment to the member cptr will change the value of the member i.

void f()
{
union { int i; char* cptr ; };
//      .
//      .
//      .
i = 5;
cptr = "string_in_union"; // overrides i
}

An anonymous union cannot have protected or private members. A global anonymous union must be declared with the keyword static .



Declarators
Initializers
C Language Levels


Example of union Declaration and Use


Incomplete Types
struct (Structure) Type
Structure and Union Member Specification
member functions
static