Main Content

Atomic variable accessed twice in an expression

Variable can be modified between accesses

Description

This defect occurs when C atomic types or C++ std::atomic class variables appear twice in an expression and there are:

  • Two atomic read operations on the variable.

  • An atomic read and a distinct atomic write operation on the variable.

The C standard defines certain operations on atomic variables that are thread safe and do not cause data race conditions. Unlike individual operations, a pair of operations on the same atomic variable in an expression is not thread safe.

Risk

A thread can modify the atomic variable between the pair of atomic operations, which can result in a data race condition.

Fix

Do not reference an atomic variable twice in the same expression.

Examples

expand all


#include <stdatomic.h>

atomic_int n = ATOMIC_VAR_INIT(0);

int compute_sum(void)
{
    return n * (n + 1) / 2;
}

In this example, the global variable n is referenced twice in the return statement of compute_sum(). The value of n can change between the two distinct read operations. compute_sum() can return an incorrect value.

Correction — Pass Variable as Function Argument

One possible correction is to pass the variable as a function argument n. The variable is copied to memory and the read operations on the copy guarantee that compute_sum() returns a correct result. If you pass a variable of type int instead of type atomic_int, the correction is still valid.


#include <stdatomic.h>

int compute_sum(atomic_int n)
{
    return n * (n + 1) / 2;
}

Result Information

Group: Concurrency
Language: C | C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: ATOMIC_VAR_ACCESS_TWICE
Impact: Medium

Version History

Introduced in R2018b