Style Case Studies: Construction Unions - Solution
(Page 2 of 9 )
Unions Redux
1. What are unions, and what purpose do they serve?
Unions allow more than one object, of either class or built-in type, to occupy the same space in memory. For example:
// Example 36-1
//
union U {
int i;
float f;
};
U u;
u.i = 42; // ok, now i is active
std::cout << u.i << std::endl;
u.f = 3.14f; // ok, now f is active
std::cout << 2 * u.f << std::endl;
But only one of the types can be “active” at a time—after all, the storage can hold only one value at a time. Also, unions support only some kinds of types, which leads us into the next question:
2. What kinds of types cannot be used as members of unions? Why do these limitations exist? Explain.
From the C++ standard:
An object of a class with a non-trivial constructor, a non-trivial copy constructor, a non-trivial destructor, or a non-trivial copy assignment operator cannot be a member of a union, nor can an array of such objects.
In brief, for a class type to be usable in a union, it must meet all the following criteria:
- The only constructors, destructors, and copy assignment operators are the compiler-generated ones.
- There are no virtual functions or virtual base classes.
- Ditto for all of its base classes and nonstatic members (or arrays thereof).
That’s all, but that sure eliminates a lot of types.
Unions were inherited from C. The C language has a strong tradition of efficiency and support for low-level close-to-the-metal programming, which has been compatibly preserved in C++; that’s why C++ also has unions. On the other hand, the C language does not have any tradition of language support for an object model supporting class types with constructors and destructors and user-defined copying, which C++ definitely does; that’s why C++ also has to define what, if any, uses of such newfangled types make sense with the “oldfangled” unions and do not violate the C++ object model including its object lifetime guarantees.
If C++’s restrictions on unions did not exist, Bad Things could happen. For example, consider what could happen if the following code were allowed:
// Example 36-2: Not standard C++ code, but what if it were allowed?
//
void f() {
union IllegalImmoralAndFattening {
std::string s;
std::auto_ptr<int> p;
};
IllegalImmoralAndFattening iiaf;
iiaf.s = “Hello, world”; // has s’s constructor run?
iiaf.p = new int(4); // has p’s constructor run?
} // will s get destroyed? should it be? will p get destroyed? should it be?
As the comments indicate, serious problems would exist if this were allowed. To avoid further complicating the language by trying to craft rules that at best might only partly patch up a few of the problems, the problematic operations were simply banished.
But don’t think that unions are only a holdover from earlier times. Unions are perhaps most useful for saving space by allowing data to overlap, and this is still desirable in C++ and in today’s modern world. For example, some of the most advanced C++ standard library implementations in the world now use just this technique for implementing the “small string optimization,” a great optimization alternative that reuses the storage inside a string object itself. Here’s the idea: For large strings, space inside the string object stores the usual pointer to the dynamically allocated buffer and housekeeping information like the size of the buffer; for small strings, however, the same space is instead reused to store the string contents directly and completely avoid any dynamic memory allocation. For more about the small string optimization (and other string optimizations and pessimizations in considerable depth), see Items 13 through 16 in More Exceptional C++ [Sutter02]; see also the discussion of current commercial std::string implementations in [Meyers01].
This chapter is from Exceptional C++ Style, by Herb Sutter (ISBN 0201760428, copyright 2005. All rights reserved. It is reprinted with permission from Addison-Wesley Professional). Check it out at your favorite bookstore today.
Buy this book now. |
Next: Dissecting Construction Unions >>
More Code Examples Articles
More By Addison-Wesley/Prentice Hall PTR