Main Content

MISRA C++:2023 Rule 12.3.1

The union keyword shall not be used

Since R2024b

Description

Rule Definition

The union keyword shall not be used.

Rationale

It is undefined behavior to access a member of a union after assigning a value to a different member of that union\ because each assignment overwrites the memory location that is shared by all members. In addition, if you access a member that has a nontrivial type such as std::string, it is your responsibility to manage the lifetime of that member.

The rule does not apply to unions that you declare by using the std::variant feature introduced in C++17. This feature throws an exception if you attempt to access a member using the wrong type or a member that is not assigned, and automatically manages the lifetimes of members of nontrivial types.

Polyspace Implementation

Polyspace® reports a declaration of a union as a violation.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <iostream>

union Pi                                     // Noncompliant
{ 
    int i;
    double d;
};

void foo(void)
{

    Pi pi;
    pi.d = 3.1416; // pi holds a double
    std::cout << "pi.d: " << pi.d << "\n";
    std::cout << "pi.i: " << pi.i << "\n";   // Undefined Behavior

    pi.i = 4; // pi holds an int
    std::cout << "pi.i: " << pi.i << "\n";
    std::cout << "pi.d: " << pi.d << "\n";   // Undefined Behavior
}

In this example, the union Pi contains a double and an int. In the code, the member d is misinterpreted as an int and the member i is misinterpret4ed as a double. These misinterpretations are undefined behaviors and might lead to bugs and implementation-dependent behavior. Polyspace reports the union declaration as a violation.

#include <iostream>
#include <string>
#include <variant>

void func()
{

    std::variant<int, std::string> myVar; // Compliant

    myVar = 10;
    std::cout << std::get<int>(myVar) << '\n';

    myVar = "Hello, World!";
    std::cout << std::get<std::string>(myVar) << '\n';
}

In this example, Polyspace does not report a violation on the union myVar. The union holds an int and an std::string member. The std::variant feature enables access by type and manages the lifetime of the std::string member.

Check Information

Group: Classes
Category: Required

Version History

Introduced in R2024b