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?
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.