C++ Unions: Usage, Syntax, and Best Practices

Cpp-unions-feature.jpg

Unions in C++ are a special data structure that is defined using the union keyword, which stores different data types in the same memory location. Also, in a union, only one member can store a value at a time, making it an efficient way to manage memory when working with different types of data. In this C++ union tutorial, we will discuss what a union in C++ is, creating a union, assigning and accessing a union, determining the size of a union, nested unions, anonymous unions, local and global unions, unrestricted unions, union-like classes, and best practices for using C++ unions.

Table of Contents:

What is a Union in C++?

A union in C++ is a special data structure that allows for storing different data types in the same memory location. It allocates enough memory to store the largest member, which means that at any given time, it can store a value of only one of its members. The size of the union is determined by the largest member.

C++ Union Syntax:

union UnionName {
type member1;
type member2;
// other members...
};

Here,

  • union: It is a keyword used to define a union.
  • UnionName: It is the name of the union, which can be any valid identifier. 
  • type: It can be any valid C++ data type, such as int, float, char, etc.
  • member1, member2: These are the members of the union.
What is a Union in C++

Declaring and Creating Unions in C++ (Syntax & Examples)

Creating a union is simple in C++. Below is a step-by-step procedure for defining, declaring, and using a C++ union:

1. Declaring a Union

At first, declare a union using the union keyword followed by the union name and its members using the given syntax.

Syntax:

union UnionName {
type member1;
type member2;
// other members...
};

2. Creating a Union Variable

Now, a union variable can be created once a union is declared.

Syntax:

UnionName variableName;

A union variable can also be created during defining the union.

Example:

union Data {
int intValue;
float floatValue;
char charValue;
} d;

When Should You Use a Union in C++?

C++ unions are best used when:

  • You need to store different types of data, but only one at a time.
  • Memory optimization is crucial.
  • You are working with hardware registers or data packets where the data format can change.

Here’s a simple C++ union example:

Cpp

Output:

When to use Cpp union

Note: Only the last value assigned (in this case data.f) remains valid.

Accessing and Modifying Union Members in C++

Accessing and assigning values to union members in C++ is also simple and easy. The member that was recently assigned can only be read because of the shared memory feature of the unions. Also, accessing any other member than the recently assigned one will lead to undefined behavior.

1. Assigning a Union in C++

A value can be assigned to a union member using the assignment operator in C++.

Example:

Cpp

Output:

Assigning a Union in Cpp

The code shows how union members are assigned and accessed in C++, since all the members share the same memory; thus, each new assignment overwrites the previous one, and then the result is printed to the console.

2. Accessing Union Members in C++

The dot operator (.) in C++ can be used to access the union members. Also, the arrow operator (->) can be used to access a union member.

Example:

Cpp

Output:

Accessing Union Members in C++

The code shows how the union members are accessed using the dot (.) operator, and only recently assigned member charVal stores a valid value due to the shared memory, which is then printed to the console.

Finding the Size of a Union in C++

Since all the members share the same memory location, thus, the size of a union is equal to the largest member of the union.

Example:

Cpp

Output:

Size of a Union in C++

The code shows that the size of a union Data 4 bytes, which is equal to the size of its largest member, is determined and printed to the console.

Nested Unions in C++ (With Code Examples)

A nested union in C++ is a union that can contain another union as a member. It is used when there is a need to organize the related data in the same memory location.

Syntax:

union OuterUnion {
data_type1 outerMember1;
data_type2 outerMember2;

union InnerUnion {
data_type3 innerMember1;
data_type4 innerMember2;
} innerUnionVar; // Optional variable name
};

A nested member can be accessed using the dot (.) operator in C++.

outer.inner.member

Example:

Cpp

Output:

Nested Unions in Cpp

The code shows how a nested union is defined, and values are assigned to id, info.marks, info.grade, which overwrites the previous value, and then all the members with values are printed to the console as a result.

Anonymous Unions in C++

An anonymous union in C++ is a union without a name that is directly declared in a scope such as global, namespace, class, or struct. The members of the anonymous union as accessed directly without any variable or union name. Also, members of an anonymous union must not have any access specifiers if the members are declared outside of the class.

Example:

Cpp

Output:

Anonymous Unions in C++

The code shows how an anonymous union is used inside a structure in which the union members, hourly wage, and salary are accessed directly without any union name, and the salary is printed to the console after being assigned.

Need for Unions in C++ 

  • Unions are needed in C++ because they save memory space by sharing space between all the members.
  • In a union, only one member can store a valid value at a time.
  • C++ unions are useful in embedded systems and also in performance-based applications.
  • A union is ideal for type-punning and low-level data interpretation.
  • C++ unions also help to store only one value at a time out of several possible types in a single variable.

Get 100% Hike!

Master Most in Demand Skills Now!

Scope of Unions in C++: Local vs Global

A union can be declared at both global and local scopes based on its use cases.

1. Global Union

A global union is declared outside of all the functions in the program. It can be accessed through a file or a program. It is used across multiple functions. Also, it can maintain its value until the program runs.

Example:

Cpp

Output:

Global Union in Cpp

The code shows how a global union, GlobalData, is declared outside the main function and also allows its variable g to be accessed and modified in the program.

2. Local Union

A local union is defined inside a function and is accessible only within the scope of that function. It is used when the union is needed temporarily and does not need to be visible globally.

Example:

Cpp

Output:

Local Union in cpp

The code shows how a local union, LocalData, is defined in the main function, in which the ch member is assigned a value, and then the values are accessed and printed to the console.

Unrestricted Unions in C++11 and Later

The unrestricted unions in C++11 and the later versions can have non-trivial types such as std::string or classes with constructors and destructors. But they need manual construction and destruction of such members by using the placement new operator and by calling destructors explicitly.

Example:

Cpp

Output:

Unrestricted Unions in C++

The code shows how an unrestricted union, which has a std::string, and the constructor and destructor are manually defined to manage this non-trivial data type member, and then it is printed with the value to the console.

Union-like Classes in C++

Union-like classes in C++ are the classes that behave like unions, as they store different types in the same memory space, but with safety and control. The union-like classes can be implemented manually using the std::variant or manual memory management in C++.

Why Use Union-like Classes?

  • Because they provide type safety and control better than the raw unions.
  • They allow non-trivial types and constructors to be used in the program.
  • They also support tagged unions by tracking the active type in the program.

Example:

Cpp

Output:

Union-like Classes

The code shows how a union-like class Wallet stores either an integer cash amount or a card name and simulates how a real wallet carries either, but not both, at once. It uses an enum for tracking the active member, and then prints the current value to the console.

Modern Alternatives to Unions in C++

In Modern C++ (C++17 and later), std::variant is an option that provides a more type-safe and flexible alternative to a union.

Example:

Cpp

Output:

Modern alternative in cpp 17

Benefits over traditional unions:

  • Type-safe (you can ensure the active type can be determined and enforced reliably at runtime).
  • Supports types with constructors and destructors.
  • No risk of accessing the wrong member results in undefined behavior.
  • Using unions still definitely has a place in performance-critical applications, but for most of modern C++, std::variant is your best option.

Union vs Structure in C++

Here is a comparison table that shows the difference between union and struct in C++:

Aspect Union Structure
Memory Shares memory among members, size is of the largest member. Allocates separate memory for each member.
Value Storage Only one member can hold a value at a time. All members can hold values independently.
Memory Efficiency More efficient, as only the largest member’s size is used. Less efficient, uses memory for all members.
Use Case Ideal for memory-sensitive scenarios such as embedded systems. Ideal when all members need to store values concurrently.
Size Size is equal to the largest member. Size is equal to the sum of the sizes of all members.
Difference between Union and Structure in C++

Benefits and Limitations of Unions in C++

Benefits:

  • Efficient Memory Usage: All members share the same memory space, making it efficient.
  • Useful in Low-Level Programming: Ideal when interfacing with hardware or handling raw memory.
  • Supports Nested Structures: Can be part of nested union C++ structures for advanced memory control.

Limitations:

  • Limited Support for Complex Types: It doesn’t support features like constructors, destructors, or non-trivial data types in older C++ standards.
  • Single Active Member: You can only access one member at a time.
  • Risk of Undefined Behavior: Misuse or incorrect usage can easily lead to undefined behavior.

Common Mistakes When Using Unions in C++

When beginners actually try to use C++ unions, they tend to make these mistakes:

  • Accessing inactive members (i.e., using a member that was not the last one written).
  • Assuming that the union stored multiple values (it does not).
  • Calling and using types that have non-trivial constructors without proper support for C++11+.
  • Not understanding the difference between union and struct in C++ could result in design mistakes.

Lastly, be careful with anonymous unions in C++. They don’t have a name. If you’re working with a large codebase, it can create confusion in large codebases if not clearly documented.

Best Practices for Using Unions in C++

  1. You should use C++ unions when there is a need for memory optimization.
  2. Always use an enum or a flag to keep track of the active member in the program.
  3. You should avoid storing non-trivial types in the traditional unions.
  4. You should not read from a member who was not the most recent writer.
  5. You must use std::variant in modern C++ wherever it is possible.
  6. Always avoid unions for complex logic and large applications.
  7. You should initialize a union carefully to maintain a consistent state.
  8. Always comment your code properly when unions are used because unions can confuse readers.

Conclusion

C++ unions are an important way to save memory space in programs by allowing multiple data types to share the same memory location. They are powerful data structures that provide type safety and low-level data handling. But also, unions are used with much more care, as they can cause errors or undefined behavior easily. So, by understanding what C++ unions are, how to declare them, how to create a union, and assigning and accessing the values, you can write efficient C++ code using unions.

If you’re learning for interviews, these C++ interview questions can help you.

Useful Resources:

C++ Unions – FAQs

Q1. What is a Union in C++?

A union in C++ is a special data structure that allows for storing different data types in the same memory location.

Q2. How is a union different from a struct?

A union stores the data types in the same memory location, and a struct stores types in different memory locations.

Q3. Can unions store multiple values at once?

No, a union cannot store multiple values at once, it can only store one value at a time.

Q4. Can unions store non-trivial types like std::string?

Yes, unions can store non-trivial types like std::string in C++11 and later versions.

Q5. What is a nested union in C++?

A nested union in C++ is a union that can contain another union as a member and also allows complex data structures to share memory.

Q6. How do you access and modify union members in C++?

Access and modify union members in C++ using the dot operator for regular unions or arrow operator for pointer-based unions.

Q7. What is the size of a union in C++ and how is it calculated?

The size of a union in C++ is equal to the size of its largest member, ensuring efficient memory usage.

Q8. What are anonymous unions in C++ and when should they be used?

Anonymous unions in C++ allow direct access to members without a union name, are useful for simpler and memory-efficient code.

Q10. What are the common mistakes when using unions in C++?

Common mistakes in C++ unions include accessing multiple members simultaneously and using unsupported non-trivial types in older standards.

About the Author

Technical Research Analyst - Full Stack Development

Kislay is a Technical Research Analyst and Full Stack Developer with expertise in crafting Mobile applications from inception to deployment. Proficient in Android development, IOS development, HTML, CSS, JavaScript, React, Angular, MySQL, and MongoDB, he’s committed to enhancing user experiences through intuitive websites and advanced mobile applications.

Full Stack Developer Course Banner