【发布时间】: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 将是