I have an atomic wrapping a chrono time_point value. The default construction of time_point is fine for me, so I expect to not need to explicitly set it. However in gcc I get a compiler error without explicitly setting the default. Here's a minimal example:
#include <atomic>
#include <chrono>
struct A
{
using TimePoint = std::chrono::system_clock::time_point;
std::atomic<TimePoint> point;
};
int
main()
{
A a;
return 0;
}
Here's the error message:
<source>: In function 'int main()':
<source>:13:7: error: use of deleted function 'A::A()'
A a;
^
<source>:6:5: note: 'A::A()' is implicitly deleted because the default definition would be ill-formed:
A() = default;
^
<source>:6:5: error: use of deleted function 'constexpr std::atomic<_Tp>::atomic() [with _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >]'
In file included from <source>:1:
/opt/compiler-explorer/gcc-8.3.0/include/c++/8.3.0/atomic:194:7: note: 'constexpr std::atomic<_Tp>::atomic() noexcept [with _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >]' is implicitly deleted because its exception-specification does not match the implicit exception-specification ''
atomic() noexcept = default;
^~~~~~
Compiler returned: 1
Here's a godbolt link: https://godbolt.org/z/YocxGd
I can work around this by simply explicitly adding a default initialization (https://godbolt.org/z/8z5WqW):
std::atomic<TimePoint> point{TimePoint{}};
But it seems silly that I would need to do that. I don't understand what is wrong. I notice that clang and gcc starting with 10.x don't complain about the implicit default. Is this just a compiler bug with the older versions of gcc? Or is there a more elegant way I should handle this than the explicit default initialization of time_point?
Note that std::atomic<std::chrono::high_resolution_clock::time_point> can not compile references this same error message but is asking about (and gets answers for) the mechanics of sharing the time_point between threads. I'm not having a problem with that. I'm asking particularly about why the implicit default constructed value isn't working when the explicit default constructed value does work.
Nice answer @Nicol - but I'm going to go with a libstdc++ bug. The following code:
#include <atomic>
struct A {
A() {}
};
int main () {
std::atomic<A> a;
}
gives a similar error on gcc 8.3/9.x, but compiles w/o error on gcc 10.x (all with -std=c++17
)
clang8 + libstdc++ 8.3 fails as well.
clang + libc++ compile w/o error.