I have a simple code:
#include <atomic>
int main()
{
std::atomic<int> a = 0;
}
This code compiles fine with GCC 11.1.0 with -std=c++17, but fails with -std=c++14 and -std=c++11.
using a deleted function std::atomic::atomic(const std::atomic&)
Why is that? In C++17 class std::atomic
still doesn't have a copy constructor. Why is this code valid for -std=c++17?
Of course I know that the preferred style is to use {}
, but I'm just curious why the code above compiles fine since C++17.
Since C++17 such copy elision is guaranteed. For std::atomic<int> a = 0;
, a
is required to be initialized from 0
directly.
Note: the rule above does not specify an optimization: C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from. Another way to describe C++17 mechanics is "unmaterialized value passing": prvalues are returned and used without ever materializing a temporary.
Before C++17, even though the copy/move operation (initializing a
from the temporary std::atomic<int>
which initialized from 0
) might be optimized out (in the copy initialization), the copy/move constructor is still required to be accessible.
The last step is usually optimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used. (until C++17)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With