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 - volatilevariant exists?
This, assuming the compiler can do whatever optimization the standard allows it to (or simply highest optimization levels).
 
    