【问题标题】:The mess that is ctime, time.h, sys/time.hctime, time.h, sys/time.h 乱七八糟
【发布时间】:2019-08-16 07:12:55
【问题描述】:

我希望一些 Linux 死忠可以回答我在使用时间函数时应该如何编写可移植 (POSIX) 代码。

  • Some SO threads suggest 在编写 C++ 代码时,包含 ctime 是正确的做法,而对于 C 代码,您仍然需要包含 time.h。但是,它们都定义了相同的函数,尽管在不同的命名空间中。从技术上讲,您应该能够同时指定两者。

  • 一篇 SO 帖子建议应避免使用基于 sys/* 的包含所有内容..

  • .. 而这个thread 意味着必须在包含 sys/resources.h 之前包含 sys/time.h,尤其是对于基于 BSD 的平台。

  • This post 表示包含 sys/time.h 可以提高可移植性。我想张贴者认为它允许您链接更多使用 gettimeofday 等特定功能的 3rd 方库.. 然而..

  • gettimeofday() 已经是discouraged,现在正在享受deprecated 状态,所以我应该使用clock_gettime() 代替。这个clock_gettime()是在time.h中定义的,见https://linux.die.net/man/3/clock_gettime..

  • .. 如果安装并链接 libavutil(例如,作为 ffmpeg-dev 的一部分),time.h was created to drive people nuts. Ffmpeg(和其他一些库)有它自己的 time.h,甚至 timeb.h。事实证明,如果您的构建堆栈中的任何 .c 或 .cpp 曾经包含 a time.h,并且包含路径包含多个有效条目 (including the one for ffmpeg),它可能指的是错误的一,声明被简单地替换。 @ FFmpeg,原因似乎是ugly hack 足以解决问题。我还没有那么幸运。此外,对所有源进行 PHP 化处理听起来根本不是一个解决方案。

  • 另一个 time.h 存在于我系统上的 usr/include/i386-linux-gnu/bits 中,因此这也不是 ffmpeg 独有的现象。简单地将 usr/include/i386-linux-gnu 称为包含路径因此变得致命,这在提及系统包含时很奇怪。

  • 我已经重写了我的 CMake 脚本,注意对大多数目标使用 dedicated include folder specs。我尝试在整个代码库中引用的预编译头文件中包含 time.h/ctime 和 sys/time.h 的各种排列。我仍然收到如下错误:

错误:字段“st_atim”的类型“timespec”不完整,struct timespec st_atim;

错误:'::time' 尚未声明

等等。

因此,对于与许多第 3 方依赖项链接的 C++ 设置,确保所有内容都能继续编译 w.r.t 的正确方法是什么?包括时间.h?我应该将系统的 time.h 包含在我正在编译的特定平台上吗?我应该检查所有可能需要 time.h 的目标吗?跳舞的大象和五彩纸屑摆在前面。


更新:该问题似乎与 C++ 的版本有关,正如下面的 cmets 中所暗示的那样。我已经将 gcc 更新到 8.3.0(从 5.4),并且我已经放弃了在 linux 上支持低于 c++11 的旧 c++ 兼容性。在更新和重建所有 3rd 方包(包括 ffmpeg)之后,我现在不再遇到我描述的问题,但这并不意味着它已经修复,因为它不会再次发生在其他人身上。事实上,我认为问题主要在于 ffmpeg 如何在较旧的编译器上编译并且没有明确要求 c++11,所以我将其保持打开状态。

【问题讨论】:

  • 正确的解决方案是:包含 并修复您的系统。我从来没有遇到过问题。
  • <time.h> 是 C 的标准标头。由于您使用的是 C++,因此您可以使用 <time.h><ctime>;不同之处在于后者将符号放入std 命名空间。使用<ctime> 被认为更好。这适用于 ISO 标准 C(因此也适用于 C++)中定义的函数和类型。 POSIX 特定函数的处理可能会有所不同(我没有检查过),但可能是相似的。据我所知,没有ctime.h(在你的标题中提到)。
  • @KeithThompson 感谢您发现错误,我在标题中修复了它。
  • @immibis:好的,那么我该如何修复我的系统,知道我想同时使用我的平台的 time.h 并使用 ffmpeg 的 libavutil 构建/链接?
  • @StarShine libavutil's one 将是

标签: c++ linux time cmake


【解决方案1】:

我建议您考虑 Howard Hinnant 的 date 库,该库已被下一版本的 C++ 标准库 (C++20) 接受:

https://github.com/HowardHinnant/date

它应该可以在任何支持C++11 以上的平台上运行。

标准版本记录在这里:https://en.cppreference.com/w/cpp/chrono

【讨论】:

  • 即将推出的 C++20 功能如何帮助编写可在当代平台上运行的可移植 Posix 代码?例如,CentOS 7 或 Ubuntu 18 LTS?一些 VPS 仍在提供 Ubuntu 14 和 16 机器。
  • @jww 我链接到的库实际上在C++11 上工作,现在已经有好几年了。它将成为即将发布的标准中的事实使其成为 imo 一个不错的选择,因为它将在未来继续提供。但是,如果您(或其他阅读此问题的人)的平台不支持 C++11,那么您(或他们)将不得不寻找其他解决方案。
  • 致反对者。你能解释一下否决票吗?
  • 感谢您的建议,很高兴知道一些标准化的东西即将到来。但是在这种情况下,它没有帮助,因为它基于 ctime(逻辑上,我同意),而 ctime 又包含 time.h,并且您会从那里得到相同的问题。
  • @StarShine 那么也许我不理解你的问题。您可以编写代码而不包含除此库之外的任何内容,也许<chrono>。无需包含<ctime> 自己或与<sys/time.h> 有任何关系。您可能需要与<ctime> 共同访问的唯一类型是std::time_t。您能否提供一个在不同 POSIX 平台上失败的代码示例?
猜你喜欢
  • 2015-06-06
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多