Main Content

MISRA C:2025 Rule 19.3

R2026b

A union member shall not be read unless it has been previously set

Since R2026b

Description

A union member shall not be read unless it has been previously set.1

Rationale

In C, all members of a union share the same region of memory. When you write to one member and then read a different member, the stored bit pattern is reinterpreted as a different type. The C standard defines this reinterpretation as undefined behavior or implementation-defined behavior, depending on the types involved. The resulting value is unpredictable and can change between compilers, optimization levels, or target platforms.

Polyspace Implementation

Polyspace® reports a violation of this rule when:

  • A union member is read after a different member was explicitly assigned in the same function.

  • The checker can determine that the active member (most recently written) differs from the member being read.

No violation is reported when the active member is unknown. The active member is unknown in these situations:

  • The union is passed as a function parameter with no assignment visible in the current scope.

  • Divergent if/else branches assign different union members.

  • A union member is written through a pointer alias.

The checker operates at function level and does not track union member activity across function calls.

As an exception, reading a character array member such as uint8_t[] is not flagged. MISRA C:2025 allows byte-level access to union storage through character arrays.

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

In this example, a function assigns the flt member of a union and then reads bits. Polyspace reports a violation because bits was not the most recently written member.


#include <stdint.h>

uint32_t get_float_bits(float value)
{
    union
    {
        float flt;
        uint32_t bits;
    } data;

    data.flt = value;
    return data.bits; // Noncompliant
}

The function writes to data.flt but then reads data.bits. To comply with this rule, read only the member that was most recently assigned.

In this example, two members of a union are written sequentially. The read of data.x after writing to data.lo is noncompliant because lo is now the active member.


#include <stdint.h>

uint32_t overwrite_read(uint32_t x)
{
    union
    {
        uint32_t x;
        uint16_t lo;
    } data;

    data.x = x;
    data.lo = 0;
    return data.x; // Noncompliant
}

After data.lo = 0, the active member is lo. Reading data.x violates the rule because x is no longer the most recently written member.

In this example, only the most recently written member is read. Polyspace does not report a violation.


#include <stdint.h>

uint32_t compliant_access(uint32_t value)
{
    union
    {
        uint32_t x;
        uint16_t lo;
    } data;

    data.x = value;
    return data.x; // Compliant
}

The function writes to data.x and reads the same member. No rule violation occurs because the read accesses the active member.

Check Information

Group: Overlapping storage
Category: Required
AGC Category: Required
PQL Name: std.misra_c_2025.R19_3

Version History

Introduced in R2026b


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C:2025

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.