Search code examples
c++gccmemory-barriersstdatomic

what happened if store with memory_order_acquire


as we know: load with memory_order_acquire, store with memory_order_release However, I found with gcc4.8.2, open -O2, a compile error throwed, /usr/include/c++/4.8.2/atomic:199:9: error: invalid memory model for '__atomic_store' but if close -O2, the error disappeared

further more, if with gcc8.3.0, the error would throwed even when with -O2

So what happend? how to explain this?


Solution

  • Without optimization, the order isn't visible as a compile-time constant to a compiler built-in, and GCC just treats runtime-variable orders as seq_cst (instead of branching on the value to skip an mfence). Optimization is required for constant-propagation to make the illegal order visible to the compiler logic that checks it, and give you the expected error.

    std::atomic<T>::store() is a function written in C++ which takes an order arg and passes that variable to the GNU C builtin __atomic_store.

    Without optimization, constant-propagation doesn't happen. Why does clang produce inefficient asm with -O0 (for this simple floating point sum)?. Even __attribute__((always_inline)) doesn't make the compiler optimize when inlining, it just avoids having an actual function call. Why is this C++ wrapper class not being inlined away?

    If you look at the resulting un-optimized asm, there's even a non-inlined call to std::operator&(std::memory_order, std::__memory_order_modifier) https://godbolt.org/z/dhViAG. But the atomic store itself inlined.