g++ std::chrono 断言中断

g++ std::chrono assertion break

我在处理 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 值的最小可能值(可能溢出?)。

我可能有两个建议:

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

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

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

23.17.5.9 duration algorithms [time.duration.alg]

template <class Rep, class Period> constexpr duration<Rep, Period> abs(duration<Rep, Period> d);

1 Remarks: This function shall not participate in overload resolution unless numeric_limits<Rep>::is_signed is true.

2 Returns: If d >= d.zero(), return d, otherwise return -d.

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

原来软件使用了EDG解析器,它需要选项--64_bit_target来避免触发assert .不幸的是,解析器文档中没有关于该选项的信息,所以我不知道为什么没有它会出现这个问题。

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