【问题标题】:Under what circumstances can time in time.h fail?time in time.h 在什么情况下会失败?
【发布时间】:2018-03-02 02:38:56
【问题描述】:

标头time.h 中的time 函数由POSIX 定义返回一个time_t,它显然可以是有符号整数或某种浮点数。

http://en.cppreference.com/w/c/chrono/time

但是,该函数在出错时返回 (time_t)(-1)

time在什么情况下会失败?

根据签名,time_t time( time_t *arg ) 似乎该函数不应该分配,因此这是一个潜在的失败原因。

【问题讨论】:

  • 您到底为什么要使用“cppreference.com”作为 C 文档的来源?是的,C++ 和 C 是相关的,但仍然不一样。对于 POSIX 的东西,使用 POSIX.1-2008 标准。对于 C 和 POSIX 函数(不包括微软设法填充到 C11 中的大多数愚蠢的 _s 函数,Windows 之外的任何人都不会使用),请使用 Linux Man Pages Online;大多数页面都包含 Conforming To 部分,该部分描述了该功能的相关标准。
  • 他们对 C 特定内容的覆盖非常好,并且该页面引用了相关标准。不过请注意,下次我会使用更好的来源。

标签: c posix


【解决方案1】:

time() 函数实际上是由 ISO 定义的,POSIX 大多遵循 ISO 定义,但它可能会对行为和/或属性(例如 8 位字节)施加更多限制。

而且,由于 ISO C 标准没有指定如何time() 可能会失败(a),因此可能性列表不受任何限制 方式:

  • 可能失败的一种方式是在嵌入式领域。您的 C 程序很可能在没有实时时钟或其他时钟硬件(甚至是计数器)的设备上运行,在这种情况下将没有时间可用。
  • 或者该函数可能检测到时钟硬件,这些硬件不断在各处跳跃,因此不可靠。
  • 或者您可能在实时环境中运行,在该环境中访问时钟硬件会耗费大量时间,因此,如果它检测到您这样做太频繁,它会决定开始失败,以便您的代码可以做它应该做的事情打算做:-)

可能性实际上是无限的,当然,我的意思是比喻意义上的“字面意思”而不是字面意思:-)


POSIX 本身明确指出,如果它检测到值不适合time_t 变量,它将失败:

如果出现以下情况,time() 函数可能会失败:[EOVERFLOW] 自 Epoch 以来的秒数不适合 time_t 类型的对象。


而且,就您的评论而言:

根据签名time_t time( time_t *arg ),该函数似乎不应该分配。

您需要对此保持谨慎。标准未规定的任何内容都完全可以解释。例如,我可以设想一个奇怪的实现,它为 NTP 请求数据包分配空间以发送到 time.nist.somewhere.org 以确保所有时间都是最新的,即使 没有 NTP 客户端 :-)


(a) 实际上,它甚至没有指定time_t定义 是什么,因此将其限制为整数或浮点值是不明智的,它可能是自大爆炸以来的两周数的字符串表示形式 :-) 它所需要的只是它可以被其他 time.h 函数使用,并且它可以在失败的情况下转换为 -1

POSIX 确实声明它表示秒数(ISO 没有),但对其没有其他限制。

【讨论】:

  • ISO C 指定 time_tclock_t 必须是“能够表示时间的真实类型”——即,time_t 必须是整数(有符号或无符号)或浮点数。 (它不能是复杂类型。)但它没有说明它如何 表示时间。它可以使用20180302204129 来表示当前时间(因为我正在输入这个)。 POSIX 提出了一些更严格的要求。
【解决方案2】:

我可以想象几个原因:

  1. 硬件计时器不可用,因为硬件不支持它。
  2. 硬件定时器刚刚失败(硬件错误,由于某种原因无法访问定时器寄存器)
  3. arg 不为空,而是指向某个非法位置。一些实现可以检测到非法指针(或捕获生成的 SEGV)并返回错误,而不是崩溃。
  4. 在提供的链接“time_t 是 32 位有符号整数的实现(许多历史实现)在 2038 年失败。”。因此,自纪元(1970 年 1 月 1 日)以来的 1

【讨论】:

  • POSIX 说 time() 失败,EOVERFLOW 如果“自纪元以来的秒数不适合 time_t 类型的对象”。
  • 那么您的意思是 2038 C 错误。
  • 是的,以及它的变体。在 64 位系统上,可能存在 Y292277026596 错误。其他系统使用了 1970 年以外的纪元。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-05
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多