Ch25: The Fine Print
Why This Chapter Exists
A tutorial has to choose an order. Some features are too small for their own chapter, too situational for the main path, or simply fall between two topics. They still appear in real code, and when they do, the compiler's behavior is often surprising.
This chapter collects the ones that were not covered earlier: the union, structured
bindings, storage duration and linkage, anonymous and inline namespaces, conditional
explicit, [[no_unique_address]], alignment, offsetof
and volatile. Each page is a set of rules, not a tour of the standard library.
One feature is deliberately not repeated here: using enum belongs with the enum
it affects, and it is already covered in
Ch2.16. Keeping it there avoids teaching the same
scope rule twice.
The Four Pages
The Short Version
A union shares one storage region among its non-static data members. Only the
active member may be read; the common initial sequence is the narrow exception. Non-trivial
members need explicit construction and destruction. Bit-fields are layout-dependent and are
not a portable wire format. Union type punning is undefined behavior in C++; use
std::bit_cast or memcpy instead.
A structured binding declares several names bound to the elements of one hidden object.
Arrays, tuple-like types and public aggregate members can be decomposed. The declaration's
qualifier applies to the hidden object: auto copies, auto&
aliases, auto const& extends a temporary, auto&&
forwards. The number of names must match the number of elements.
Scope, storage duration and linkage are independent. A local static is one
object per program, initialized once. thread_local is one object per thread, not
synchronization. inline variables give one entity across translation units in a
header. Namespace-scope const has internal linkage by default. Anonymous
namespaces are per-translation-unit implementation details; inline namespaces are
transparent versioning.
explicit(bool) makes explicitness a compile-time condition.
[[no_unique_address]] permits empty members to overlap, but does not guarantee
a size. alignas raises alignment; alignof asks for it.
offsetof is for standard-layout types and is ABI-dependent.
volatile is for hardware and signals, not for inter-thread synchronization.
Key Takeaways
- A union provides one storage for many types; tracking the active member is your job.
- Structured bindings decompose aggregates and tuple-like types.
- Storage duration, linkage and namespaces determine lifetime and visibility.
- The sharp edges are real; prefer the safer construct when it exists.