Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

198
Views
Can I perform arithmetic operations on an atomic variable directly?

Can I perform arithmetic operations on an atomic variable directly?

Since I find the C standard library provides a lot of utility functions like atomic_fetch_add to perform the addition between an atomic variable and a non-atomic variable. But, I am curious since the variable is atomic, can I have arithmetic operations directly on it? Like in the code shown below:

#include <threads.h>
#include <stdio.h>
#include <stdatomic.h>
atomic_int i = 0;
int run(void* v) {
  i += 100;  // <- is this operaiton thread-safe?
  // atomic_fetch_add(&i, 100);
  printf("%d\n", i);
  return thrd_success;
}
int main(void) {
  thrd_t thread;  
  thrd_create(&thread, run, NULL);
  thrd_join(thread, NULL);
  return 0; 
} 
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Compound assignments to variables with atomic types are explicitly allowed in C2011: quoting N1570 §6.15.6.2p3

A compound assignment of the form E1 op= E2 is equivalent to the simple assignment expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. If E1 has an atomic type, compound assignment is a read-modify-write operation with memory_order_seq_cst memory order semantics. [footnote 113]

Emphasis mine. Footnote 113 goes on to give a specific example of how E1 op= E2 can be translated into <stdatomic.h> primitive operations when E1 is an atomic type.

The other operators that I'm confident one may apply to atomic types are postfix ++ and --, which are also guaranteed to perform an atomic read-modify-write (§6.5.2.4), and simple assignment, which is guaranteed to perform an atomic load or store as appropriate (§6.2.6.1).

Caution: Prefix ++ and -- are not guaranteed to perform an atomic read-modify-write (compare 6.5.2.4 with 6.5.3.1).

I read this sentence of 6.2.6.1

Loads and stores of objects with atomic types are done with memory_order_seq_cst semantics.

as implying that is valid to use an atomic lvalue as an operand to most other operators, and an atomic load is performed, after which the value is not treated specially. Don't quote me on this part.

C++ may have different rules. I will leave exegesis of the C++ standard to someone else.

over 4 years ago · Santiago Trujillo Report

0

The i += 10; statement maintains the atomicity of i, because it is used as an lvalue expression. From cppreference (bolding mine):

Built-in increment and decrement operators and compound assignment are read-modify-write atomic operations with total sequentially consistent ordering (as if using memory_order_seq_cst). If less strict synchronization semantics are desired, the standard library functions may be used instead.

The example given on the linked page uses the built-in (pre-)increment operation on the acnt variable, but it could just as well have used a compound assignment, as your code does.

However, more complex arithmetic operations may cause the i variable to lose its atomicity, if it is not used strictly as an lvalue expression. From the same page:

Atomic properties are only meaningful for lvalue expressions. Lvalue-to-rvalue conversion (which models a memory read from an atomic location to a CPU register) strips atomicity along with other qualifiers.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!