Main Page

Previous Page
Next Page

[Page 1262 (continued)]

E.12. Unions

A union (defined with keyword union) is a region of memory that, over time, can contain objects of a variety of types. However, at any moment, a union can contain a maximum of one object, because the members of a union share the same storage space. It is the programmer's responsibility to ensure that the data in a union is referenced with a member name of the proper data type.

Common Programming Error E.3

The result of referencing a union member other than the last one stored is undefined. It treats the stored data as a different type.

[Page 1263]

Portability Tip E.2

If data are stored in a union as one type and referenced as another type, the results are implementation dependent.

At different times during a program's execution, some objects might not be relevant, while one other object isso a union shares the space instead of wasting storage on objects that are not being used. The number of bytes used to store a union will be at least enough to hold the largest member.

Performance Tip E.3

Using unions conserves storage.

Portability Tip E.3

The amount of storage required to store a union is implementation dependent.

A union is declared in the same format as a struct or a class. For example,

     union Number
        int x;
        double y;

indicates that Number is a union type with members int x and double y. The union definition must precede all functions in which it will be used.

Software Engineering Observation E.4

Like a struct or a class declaration, a union declaration simply creates a new type. Placing a union or struct declaration outside any function does not create a global variable.

The only valid built-in operations that can be performed on a union are assigning a union to another union of the same type, taking the address (&) of a union and accessing union members using the structure member operator (.) and the structure pointer operator (->). unions cannot be compared.

Common Programming Error E.4

Comparing unions is a compilation error, because the compiler does not know which member of each is active and hence which member of one to compare to which member of the other.

A union is similar to a class in that it can have a constructor to initialize any of its members. A union that has no constructor can be initialized with another union of the same type, with an expression of the type of the first member of the union or with an initializer (enclosed in braces) of the type of the first member of the union. unions can have other member functions, such as destructors, but a union's member functions cannot be declared virtual. The members of a union are public by default.

Common Programming Error E.5

Initializing a union in a declaration with a value or an expression whose type is different from the type of the union's first member is a compilation error.

[Page 1264]

A union cannot be used as a base class in inheritance (i.e., classes cannot be derived from unions). unions can have objects as members only if these objects do not have a constructor, a destructor or an overloaded assignment operator. None of a union's data members can be declared static.

Figure E.8 uses the variable value of type union Number to display the value stored in the union as both an int and a double. The program output is implementation dependent. The program output shows that the internal representation of a double value can be quite different from the representation of an int.

Figure E.8. Printing the value of a union in both member data types.
(This item is displayed on pages 1264 - 1265 in the print version)

 1  // Fig. E.8: figE_08.cpp
 2  // An example of a union.
 3  #include <iostream>
 4  using std::cout;
 5  using std::endl;
 7  // define union Number 
 8  union Number           
 9  {                      
10     int integer1;       
11     double double1;     
12  };  // end union Number
14  int main()
15  {
16     Number value; // union variable
18     value.integer1 = 100; // assign 100 to member integer1
20     cout << "Put a value in the integer member\n"
21          << "and print both members.\nint:  "
22          << value.integer1 << "\ndouble: " << value.double1
23          << endl;
25     value.double1 = 100.0;  // assign 100.0 to member double1
27     cout << "Put a value in the floating member\n"
28          << "and print both members.\nint:  "
29          << value.integer1 << "\ndouble: " << value.double1
30          << endl;
32     return 0;
33  }  // end main

  Put a value in the integer member
  and print both members.
  int:   100
  double: -9.25596e+061
  Put a value in the floating member
  and print both members.
  int:   0
  double: 100

An anonymous union is a union without a type name that does not attempt to define objects or pointers before its terminating semicolon. Such a union does not create a type but does create an unnamed object. An anonymous union's members may be accessed directly in the scope in which the anonymous union is declared just as are any other local variablesthere is no need to use the dot (.) or arrow (->) operators.

[Page 1265]

Anonymous unions have some restrictions. Anonymous unions can contain only data members. All members of an anonymous union must be public. And an anonymous union declared globally (i.e., at file scope) must be explicitly declared static. Figure E.9 illustrates the use of an anonymous union.

Figure E.9. Using an anonymous union.
(This item is displayed on pages 1265 - 1266 in the print version)

 1  // Fig. E.9: figE_09.cpp
 2  // Using an anonymous union.
 3  #include <iostream>
 4  using std::cout;
 5  using std::endl;
 7  int main()
 8  {
 9     // declare an anonymous union                                
10     // members integer1, double1 and charPtr share the same space
11     union                                                        
12      {                                                           
13        int integer1;                                             
14        double double1;                                           
15        char *charPtr;                                            
16      }; // end anonymous union                                   
18     // declare local variables
19     int integer2 = 1;
20     double double2 = 3.3;
21     char *char2Ptr = "Anonymous";
23     // assign value to each union member
24     // successively and print each
25     cout << integer2 << ' ';
26     integer1 = 2;
27     cout << integer1 << endl;
29     cout << double2 << ' ';
30     double1 = 4.4;
31     cout << double1 << endl;
33     cout << char2Ptr << ' ';
34     charPtr = "union";
35     cout << charPtr << endl;
37     return 0;
38  }  // end main

  1 2
  3.3 4.4
  Anonymous union

Previous Page
Next Page