I have a class that has a member variable that wraps a std time_point in an atomic. I'm having a hard time getting older compilers happy with it. I initially had issues with versions of GCC earlier than 10 accepting it. I addressed this via explicitly initializing it.
I thought that made all the compilers happy. But once my code got into production, I faced an issue in the more thorough CI (in comparison to the PR CI) with older clang compilers. The project is Apache Traffic Server, so it is open sourced, if viewing it is interesting. Here is the code:
https://github.com/apache/trafficserver/blob/master/include/tscore/Throttler.h#L117
Here is a minimal example that demonstrates the problem:
#include <atomic>
#include <chrono>
struct A {
A() {}
using Clock = std::chrono::system_clock;
using TimePoint = Clock::time_point;
// The explicit initialization is needed by
// GCC earlier than 10.
std::atomic<TimePoint> _last_allowed_time{TimePoint{}};
};
The error can be reproduced in godbolt: https://godbolt.org/z/4db4osf66
Here's the error:
In file included from <source>:1:
/opt/compiler-explorer/gcc-8.3.0/lib/gcc/x86_64-linux-gnu/8.3.0/../../../../include/c++/8.3.0/atomic:194:7: error: exception specification of explicitly defaulted default constructor does not match the calculated one
atomic() noexcept = default;
^
<source>:12:26: note: in instantiation of template class 'std::atomic<std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1, 1000000000> > > >' requested here
std::atomic<TimePoint> _last_allowed_time{TimePoint{}};
^
1 error generated.
Compiler returned: 1
Playing with the godbolt configuration, anything newer than clang 9 does not raise this error. I can ifdef around it, I suppose, but I'm not sure what the workaround is if I do. The explicit initialization made gcc happy. What can I do to make clang 8 and earlier happy with this construction?
By the way, this question is related to the following: Program with "noexcept" constructor accepted by gcc, rejected by clang
While that question discusses whether clang or gcc is right about the error or lack of error, I'm not concerned about what is theoretically correct for the compiler to do. It seems like both clang and gcc agree in later versions that this is OK as formed. That's good, but not helpful for a project that needs to support older compilers. My question asks what I can do to make the older compilers happy.