【问题标题】:g++ std::chrono assertion breakg++ std::chrono 断言中断
【发布时间】:2019-02-20 06:51:59
【问题描述】:

我在处理 C++ 项目中的一些代码时遇到了问题。它包含std::chrono 库,并在以下断言处不断中断:

static_assert(system_clock::duration::min() < system_clock::duration::zero(), "a clock's minimum duration cannot be less than its epoch");

断言破坏了具有 g++ 6.3.0 的 Debian 机器和具有 Windows 10、CygWin 和 g++ 7.3.0 的 PC 中的代码。 我还在在线 C++ 编译器中尝试了一个简单的示例,包括 chrono 库,它本身不会产生任何问题,但是当手动比较 chrono 系统时钟的最小持续时间和零持续时间时,会给出应该触发断言的结果好吧。

我已经搜索了该问题,并发现了一些线索,这些线索导致了由包含时区信息的 TZ posix 变量引起的一些相关问题。尝试取消设置并将其设置为正确的值,但它对断言没有影响。

如果有任何指示或建议,我将不胜感激。

编辑: 虽然 std::chrono::milliseconds::zero() 的值(如预期的那样)为 0,但 std::chrono::milliseconds::min() 的值是 -9223372036854775808 或 -2^63,我认为这是 long long 值的最小可能值(可能溢出?)。

【问题讨论】:

标签: c++ std assert chrono


【解决方案1】:

经过一些测试后,我意识到断言在两个系统中在通过正在使用的测试软件使用 g++ 时被触发,因为在它外部编译的相同代码不会以相同的方式使断言失败编译器。

原来软件使用EDG解析器,需要--64_bit_target选项来避免触发断言。不幸的是,解析器文档中不存在有关该选项的信息,因此我不知道没有它会发生此问题的原因。

现在可能这个问题没有多大价值,但我不想删除它,因为人们已经写了一些人可能感兴趣的答案。

【讨论】:

    【解决方案2】:

    持续时间可以是负数,正如您在 ...::min() 的高度负值中发现的那样。断言不正确,几乎就像断言 -1 必须大于零一样。

    C++17 规范声明了一个用于查找绝对持续时间的 abs() 函数,并讨论了它对有符号和无符号表示的适用性:

    23.17.5.9 持续时间算法 [time.duration.alg]

    template &lt;class Rep, class Period&gt; constexpr duration&lt;Rep, Period&gt; abs(duration&lt;Rep, Period&gt; d);

    1 备注:除非 numeric_limits::is_signed 为真,否则该函数不应参与重载决议。

    2 返回:如果 d >= d.zero(),则返回 d,否则返回 -d。

    【讨论】:

      【解决方案3】:

      我可能有两个建议:

      1. 一般情况下,断言失败只发生在调试版本,所以如果你 只想构建成功,可以构建发布版本到 避免问题。
      2. 您可以在适当的时区确认您的 Debian 和 Windows 时区。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多