gpt4 book ai didi

c++ - 如何使旧版本的 clang 对 atomic 的默认异常规范感到满意

转载 作者:行者123 更新时间:2023-12-04 07:52:53 25 4
gpt4 key购买 nike

我有一个具有成员变量的类,该类将 std time_point 包装在原子中。我很难让老编译器对它感到满意。我最初在接受 GCC 10 之前的版本时遇到了问题。我通过显式初始化它来解决这个问题。
我认为这让所有编译器都感到高兴。但是一旦我的代码投入生产,我在更彻底的 CI(与 PR CI 相比)和旧的 clang 编译器中遇到了一个问题。该项目是Apache Traffic Server,所以它是开源的,如果查看它很有趣。这是代码:
https://github.com/apache/trafficserver/blob/master/include/tscore/Throttler.h#L117
这是一个演示问题的最小示例:

#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{}};
};
该错误可以在godbolt中重现:
https://godbolt.org/z/4db4osf66
这是错误:
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
使用 Godbolt 配置,任何比 clang 9 更新的版本都不会引发此错误。我想我可以 ifdef 解决它,但我不确定如果我这样做,解决方法是什么。显式初始化使 gcc 感到高兴。我该怎么做才能让 clang 8 及更早的版本对这种结构感到满意?

顺便说一下,这个问题与以下内容有关:
Program with "noexcept" constructor accepted by gcc, rejected by clang
虽然该问题讨论了 clang 或 gcc 关于错误或没有错误是否正确,但我并不关心编译器在理论上正确的做法。似乎 clang 和 gcc 在以后的版本中都同意这是可以形成的。这很好,但对需要支持旧编译器的项目没有帮助。我的问题是我可以做些什么来让旧的编译器满意。

最佳答案

作为解决方法,您可以制作 TimePoint一个子类(带有 noexcept 默认构造函数)而不是 typedef。

#include <atomic>
#include <chrono>

struct A {
A() {}

using Clock = std::chrono::system_clock;
class TimePoint : public Clock::time_point {
public:
using time_point::time_point;
constexpr TimePoint() noexcept : time_point() {}
};

std::atomic<TimePoint> last_allowed_time_;
};
这在所有 GCC ≥4.8.1 和 clang ≥3.4.1 的 Godbolt 上编译(使用 -std=c++1y)。
编辑:另外,请注意,以下划线开头的标识符是为实现保留的。我喜欢使用尾随下划线(即 last_allowed_time_ 而不是 _last_allowed_time )。

关于c++ - 如何使旧版本的 clang 对 atomic 的默认异常规范感到满意,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66862690/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com