V2647. MISRA. Structure and union members of atomic objects should not be directly accessed.
This diagnostic rule is based on the MISRA (Motor Industry Software Reliability Association) software development guidelines.
This diagnostic rule is relevant only for C.
Direct access (the .
or ->
operator) to structure data members or unions of atomic type objects can result in a data race. Instead, access the object using the special functions from <stdatomic.h>
and the =
assignment operator.
The C standard defines the following functions for accessing atomic objects:
atomic_init
atomic_store
atomic_load
atomic_exchange
atomic_compare_exchange
The standard guarantees that performing atomic operations on data that is used across multiple threads will not result in a data race. However, direct access to data members of atomic type objects violates this guarantee.
Note. The atomic_init
function alone does not prevent a potential data race. If multiple threads access a variable at initialization—even when atomic operations are used—it can still cause a race condition.
An example of erroneous code:
typedef struct {
int32_t width;
int32_t height;
} rectangle_t;
_Atomic rectangle_t rect;
int foo(void)
{
rect.width = 300;
return 0;
}
In the example, directly writing rect.width = 300;
can cause data races and an invalid object state.
The MISRA guidelines suggest fixing such code as follows:
typedef struct {
int32_t width;
int32_t height;
} rectangle_t;
_Atomic rectangle_t rect;
int foo(void)
{
rectangle_t tmp;
tmp = atomic_load(&rect);
tmp.height = 400;
atomic_store(&rect, tmp);
return 0;
}
However, this fix alone is insufficient. Although the issue of changing non-atomic data members in the structure has been resolved, a new potential synchronization issue has been added.
Let's look at the following scenario:
- The first thread calls the
foo
function and copies the structure to thetmp
variable. - While the first thread is changing the
tmp.height
value, the second one can change therect.width
value. - The first thread calls the
atomic_store
function and overwritesrect.width
with the old value. This is an error.
To avoid this issue, additional synchronization between different threads may be required. However, this topic is beyond the scope of the MISRA diagnostic rule.
This diagnostic is classified as:
|