Unions:
Unions
suggest changeUnions are very useful tools, but come with a few important caveats:
- It is undefined behavior, per the C++ standard, to access an element of a union that was not the most recently modified member. Although a lot of C++ compilers permit this access in well defined ways, these are extensions and cannot be guaranteed across compilers.
A std::variant (since C++17) is like a union, only it tells you what it currently contains (part of its visible state is the type of the value it holds at a given moment: it enforces value access happening only to that type).
- Implementations do not necessarily align members of different sizes to the same address.
Basic Union Features
Unions are a specialized struct within which all members occupy overlapping memory.
union U {
int a;
short b;
float c;
};
U u;
//Address of a and b will be equal
(void*)&u.a == (void*)&u.b;
(void*)&u.a == (void*)&u.c;
//Assigning to any union member changes the shared memory of all members
u.c = 4.f;
u.a = 5;
u.c != 4.f;
Typical Use
Unions are useful for minimizing memory usage for exclusive data, such as when implementing mixed data types.
struct AnyType {
enum {
IS_INT,
IS_FLOAT
} type;
union Data {
int as_int;
float as_float;
} value;
AnyType(int i) : type(IS_INT) { value.as_int = i; }
AnyType(float f) : type(IS_FLOAT) { value.as_float = f; }
int get_int() const {
if(type == IS_INT)
return value.as_int;
else
return (int)value.as_float;
}
float get_float() const {
if(type == IS_FLOAT)
return value.as_float;
else
return (float)value.as_int;
}
};
Undefined Behavior
union U {
int a;
short b;
float c;
};
U u;
u.a = 10;
if (u.b == 10) {
// this is undefined behavior since 'a' was the last member to be
// written to. A lot of compilers will allow this and might issue a
// warning, but the result will be "as expected"; this is a compiler
// extension and cannot be guaranteed across compilers (i.e. this is
// not compliant/portable code).
}
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents
1
Literals
8
Arrays
11
Loops
14
keywords
16
auto keyword
17
Pointers
20
std::string
21
Enumeration
22
std::atomic
23
std::vector
24
std::array
25
std::pair
26
std::map
29
std::any
30
std::variant
35
std::iomanip
36
Iterators
37
Basic I/O
38
File I/O
39
Streams
43
References
44
Polymorphism
51
Unions
52
Templates
53
Namespaces
56
Lambdas
57
Threading
59
Preprocessor
60
SFINAE
62
RAII
63
Exceptions
67
Sorting
74
Pimpl idiom
75
Copy elision
78
Singleton
81
Type erasure
84
RTTI
87
Scopes
88
Atomic types
90
constexpr
98
Type traits
102
Attributes
104
Profiling
107
Recursion
108
Callable objects
111
Inline functions
113
Header files
116
Parameter packs
117
Iteration
118
type deduction
120
Build systems
122
Type inference
125
Alignment
126
Inline variables
133
Optimization
134
Semaphore
136
Debugging
139
Mutexes
140
Recursive mutex
141
Unit testing
142
decltype
143
Digit separators
144
C++ Containers
146
Contributors