首页 > 解决方案 > 符合标准的 C++ 实现如何表明它不知道当前日期和时间?

问题描述

一些 C++ 实现(例如,电池供电的嵌入式设备)可能没有用或无法跟踪当前日期和时间。

C 标准特别允许这样的实现。引用 ISO/IEC 9899:1999 7.23.2.4(强调我的):

time 函数返回实现对当前日历时间的最佳近似值。如果日历时间不可用,则返回值 (time_t)(-1)。

C++11 引入了从系统范围的实时时钟获取挂钟时间的chrono库和函数。std::chrono::system_clock::now()该函数被声明为noexcept,因此它不能抛出任何异常来指示不可用,也不允许返回任何特殊值(如-1在 C 的情况下)。

但是对于 C++11、C++14 和 C++17,仍然存在漏洞。该标准没有指定时钟的纪元,因此符合标准的实现可以将纪元设置为上电(或程序启动)时的时间点,并且仍然满足标准的要求。

目前的 C++20 草案将填补这个漏洞并要求system_clock使用 Unix 时间。换句话说,不知道当前时间的 C++ 实现是不合格的。

这是标准委员会的疏忽吗?符合标准的 C++ 实现如何表明它不知道当前日期和时间?

(请注意,在标准的其他部分,此问题已得到解决。例如,如果实时时间和日期不可用,则实现可以将__TIME__和宏设置为实现定义的值。)__DATE__

标签: c++timelanguage-lawyerchronoc++20

解决方案


知道时间和知道正确时间是有区别的。

如果这样的设备打开,它可以自由地假设它的 CPU 周期计数器(或任何权力steady_clock)代表自 UNIX 时间以来的周期数。也就是说,它可以假设它是在 UNIX 纪元的那一刻开启的。这将是system_clock. 那个时间可能在某种绝对意义上是不正确的,但它将是一个符合 C++20 的实现。

该标准只要求system_clock' 的时代是 UNIX 时间(或者更具体地说,我们都可以假设它是 UNIX 时间)。这并不意味着为时钟检索到的滴答计数保证是全球准确的当前时间。毕竟,用户可以在技术上更改当前时间,这意味着要反映在system_clock(这就是为什么它不需要是稳定时钟的原因)。

因此,您永远不能假设它system_clock准确地代表了当前时间;它只代表运行环境认为的当前时间。因此,无法chrono解释当前时间在某种意义上是否“正确”。

system_clock基本上是为了提供最接近系统可以提供或理解的正确时间的任何内容。如果系统可以做的最好的事情是假设设备在 UNIX 时代打开,那么这就是你得到的。

此外,由于system_clock(以及所有<chrono>这些)不在独立需求列表中,因此此类设备的 C++ 实现可能是独立实现。因此他们选择根本不实施system_clock(或全部<chrono>)。


推荐阅读