Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This compliant solution uses a compare-and-exchange to guarantee that the correct value is stored in flag. All updates are visible to other threads. The call to atomic_compare_exchange_weak() is in a loop in conformance with CON41-C. Wrap functions that can fail spuriously in a loop.

Code Block
bgColor#ccccFF
langc
#include <stdatomic.h>
#include <stdbool.h>
 
static atomic_bool flag = ATOMIC_VAR_INIT(false);
 
void init_flag(void) {
  atomic_init(&flag, false);
}
 
void toggle_flag(void) {
  bool old_flag = atomic_load(&flag);
  bool new_flag;
  do {
    new_flag = !old_flag;
  } while (!atomic_compare_exchange_weak(&flag, &old_flag, new_flag));
}
   
bool get_flag(void) {
  return atomic_load(&flag);
}

An alternative solution is to use the atomic_flag data type for managing Boolean values atomically. However, atomic_flag does not support a toggle operation.

Compliant Solution (Compound Assignment)

This compliant solution uses the ^=  assignment operation to toggle flag. This operation is guaranteed to be atomic, according to the C Standard, 6.5.17.5, paragraph 3 [ISO/IEC 9899:2024]. This operation performs a bitwise-exclusive-or between its arguments, but for Boolean arguments, this is equivalent to negation.

Code Block
bgColor#ccccFF
langc
#include <stdatomic.h>
#include <stdbool.h>
  
static atomic_bool flag = ATOMIC_VAR_INIT(false);
  
void toggle_flag(void) {
  flag ^= 1;
}
    
bool get_flag(void) {
  return flag;
}

An alternative solution is to use a mutex to protect the atomic operation, but this solution loses the performance benefits of atomic variables.

Noncompliant Code Example

This noncompliant code example takes an atomic global variable n and computes n + (n - 1) + (n - 2) + ... + 1, using the formula n * (n + 1) / 2:

Code Block
bgColor#FFcccc
langc
#include <stdatomic.h>

atomic_int n = ATOMIC_VAR_INIT(0);
  
int compute_sum(void) {
  return n * (n + 1) / 2;
}

The value of n may change between the two atomic reads of n in the expression, yielding an incorrect result.

Compliant Solution

This compliant solution passes the atomic variable as a function argument, forcing the variable to be copied and guaranteeing a correct result. Note that the function's formal parameter need not be atomic, and the atomic variable can still be passed as an actual argument.

Code Block
bgColor#ccccff
langc
#include <stdatomic.h>
 
int compute_sum(int n) {
  return n * (n + 1) / 2;
}

Risk Assessment

When operations on atomic variables are assumed to be atomic, but are not atomic, surprising data races can occur, leading to corrupted data and invalid control flow.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

CON40-C

Medium

Probable

Medium

P8

L2

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V
multiple-atomic-accessesPartially checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-CON40
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

CONCURRENCY.MAA

Multiple Accesses of Atomic
Coverity
Include Page
Coverity_V
Coverity_V

EVALUATION_ORDER (partial)

MISRA 2012 Rule 13.2

VOLATILE_ATOICITY (possible)

Implemented
Cppcheck Premium

Include Page
Cppcheck Premium_V
Cppcheck Premium_V

premium-cert-con40-cPartially implemented
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C1114, C1115, C1116

C++3171, C++4150


Klocwork
Include Page
Klocwork_V
Klocwork_V

CERT.CONC.ATOMIC_TWICE_EXPR


Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_C-CON40-a

Do not refer to an atomic variable twice in an expression

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule CON40-C

Checks for:

  • Atomic variable accessed twice in an expression
  • Atomic load and store sequence not atomic

Rule fully covered.

RuleChecker

Include Page
RuleChecker_V
RuleChecker_V

multiple-atomic-accessesPartially checked

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

CWE 2.11CWE-366, Race Condition within a Thread2017-07-07: CERT: Rule subset of CWE

CERT-CWE Mapping Notes

Key here for mapping notes

CWE-366 and CON40-C

CON40-C = Subset( CON43-C) Intersection( CON32-C, CON40-C) = Ø

CWE-366 = Union( CON40-C, list) where list =


  • C data races that do not involve an atomic variable used twice within an expression



Bibliography

[ISO/IEC 9899:2024]

6.5.17.3, "Compound Assignment"
7.17, "Atomics"