I noticed that most member functions of std::atomic<T>
types are declared twice, once with the volatile
modifier and once without (example)). I checked the source code of the G++ standard library implementation and I found all of them to be exact duplicates, for example,
bool
load(memory_order __m = memory_order_seq_cst) const noexcept
{ return _M_base.load(__m); }
bool
load(memory_order __m = memory_order_seq_cst) const volatile noexcept
{ return _M_base.load(__m); }
I could not find any example where the volatile
variant behaves differently than the non-volatile
one, differs in return type or anything of that sort.
Why is that? I thought a volatile
member function could also be called in objects which are not volatile
. So declaring and defining std::atomic::load(...) const volatile noexcept
etc. should be enough.
Update:
Based on the comments my question basically boils down to: Can you provide an example where some calls using a non-volatile
instance (not necessarily of std::atomic
) would generate a different assembly in the two following cases,
every member function appears with the same body with and without
volatile
,only the
volatile
variant exists?
This, assuming the compiler can do whatever optimization the standard allows it to (or simply highest optimization levels).