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?
You use it in some function so you cannot say it may be optimized out. If you replace a atomic operation with external function it will be the same: https://godbolt.org/z/GsYjrb6z5