C++ compilers are allowed to elide or combine allocations. However, it seems that if allocated memory is accessed with atomic operations (even with relaxed memory order) that allocation cannot be elided by GCC and Clang.
// new/delete are elided
uint64_t successfulElision() {
auto ptr = new uint64_t{0};
*ptr = 5;
auto result = *ptr;
delete ptr;
return result;
}
// new/delete are not elided
uint64_t failedElision() {
auto ptr = new uint64_t{0};
atomic_ref<uint64_t> rf(*ptr);
rf.store(5, memory_order_relaxed);
auto result = rf.load(memory_order_relaxed);
delete ptr;
return result;
}
https://godbolt.org/z/sacMdbac5
What is the reason for this? Is this required by the standard?