根据 POSIX 的字母,您实际上可能需要运行时测试,即使常量CLOCK_MONOTONIC
被定义为。处理这个问题的官方方法是使用_POSIX_MONOTONIC_CLOCK
“功能测试宏”,但这些宏的语义非常复杂:引用http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html ,
如果未定义符号常量或定义了值 -1,则不支持编译该选项。如果它定义的值大于零,则在执行应用程序时应始终支持该选项。如果它被定义为零值,则该选项应支持编译,并且在运行时可能支持也可能不支持。
将这种三向区别转化为代码会得到如下所示的结果:
#if !defined _POSIX_MONOTONIC_CLOCK || _POSIX_MONOTONIC_CLOCK < 0
clock_gettime(CLOCK_REALTIME, &spec);
#elif _POSIX_MONOTONIC_CLOCK > 0
clock_gettime(CLOCK_MONOTONIC, &spec);
#else
if (clock_gettime(CLOCK_MONOTONIC, &spec))
clock_gettime(CLOCK_REALTIME, &spec));
#endif
但是,如果您始终在定义 CLOCK_MONOTONIC 本身时进行运行时测试,则它会更简单且更具可读性:
#ifdef CLOCK_MONOTONIC
if (clock_gettime(CLOCK_MONOTONIC, &spec))
#endif
clock_gettime(CLOCK_REALTIME, &spec);
在支持的当前一代操作系统上,这会增加代码的大小一些微不足道的量CLOCK_MONOTONIC
,但在我看来,可读性的好处是值得的。
还有一个非常有力的理由支持使用CLOCK_MONOTONIC
无条件地;您更有可能找到不支持的操作系统clock_gettime
与具有该功能的操作系统相比,根本没有(例如,据我所知,MacOS X 仍然没有它)clock_gettime
但不是CLOCK_MONOTONIC
.