The mess that is ctime, time.h, sys/time.h

The mess that is ctime, time.h, sys/time.h

本文关键字:time sys ctime mess that is The      更新时间:2023-10-16

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

  • 一些 SO 线程建议在编写C++代码时包含 ctime 是正确的做法,而您仍然会为 C 代码包含 time.h。但是,它们都定义了相同的函数,尽管在不同的命名空间中。从技术上讲,您应该能够同时指定两者。

  • 一个SO帖子建议应该避免使用基于sys/*的包含。

  • .. 虽然这个线程意味着在包含 sys/resources.h 之前必须包含 sys/time.h,特别是对于基于 BSD 的平台。

  • 这篇文章说包括sys/time.h可以提高可移植性。我想海报认为它允许你链接更多使用特定函数(如gettimeofday)的第三方图书馆。然而。。

  • gettimeofday()已被劝阻,现在正在享受弃用状态,所以我应该改用 clock_gettime()。这个clock_gettime()在 time.h 中定义,请参见 https://linux.die.net/man/3/clock_gettime..

  • .. 如果安装并与 libavutil 链接(例如作为 FFMPEG-dev 的一部分),很明显 time.h 的创建是为了让人们发疯。Ffmpeg(和其他一些库)有自己的time.h,甚至timeb.h。事实证明,如果构建堆栈中任何地方的任何 .c 或.cpp都包含 time.h,并且包含路径包含多个有效条目(包括用于 ffmpeg 的条目),则它可能引用了错误的条目,并且声明被简单地替换。@ FFmpeg,理由似乎是丑陋的黑客足以解决问题。我还没那么幸运。此外,对所有源代码进行 PHP 化听起来根本不像是一种解决方案。

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

  • 我重写了我的 CMake 脚本,注意为大多数目标使用专用的包含文件夹规范。我尝试过在整个代码库中引用的预编译标头中包含 time.h/ctime 和 sys/time.h 的各种排列。我仍然收到以下错误:

错误:字段"st_atim"的类型不完整"时间规范",结构时间规范st_atim;

错误:"::时间"尚未声明

等。。

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


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

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

):https://github.com/HowardHinnant/date

它应该适用于任何支持C++11以上的平台。

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