Search code examples
catomicc11

C11 mixing atomic and non-atomic access to variable


Sometimes you may want to access a variable both atomically and non-atomically. Which is why I find convinient that on gcc you can write something like :

int var = 0;
var++;
atomic_fetch_add(&var, 1);

However this does not compile with clang 4.0.1 :

error: address argument to atomic operation must be a pointer to _Atomic type ('int *' invalid)
atomic_fetch_add(&var, 1);

The best solution I could find is a cast :

int var = 0;
(*(int*)&var)++;
atomic_fetch_add(&var, 1);

Is there a simpler and portable way to achieve this ?


Solution

  • The abstract machine defined by the C Standard has a rather different view of storage than most real machines. In particular, rather than thinking of memory accesses as actions which can be performed in a variety of different way depending upon required circumstances, it instead views each object has supporting one kind of read and at most one kind of write (const-qualified objects don't support any kind of write); the kind of read and write required to access an object depend upon its type.

    Such an approach may be useful for some kinds of hardware platforms, or for some optimization strategies, but is grossly unsuitable for many kinds of programs running on real-world platforms. Unfortunately, the Standard doesn't recognize any practical way by which programmers can indicate that certain objects should be treated as "ordinary" storage most of the time, but recognize that they require more precise memory semantics at certain specific times during program execution.