我正在尝试编写一个小型 C++ 实用程序库,它(除其他外)使 clock_gettime() API 在几乎任何平台上都可用。* 基本上,我想检查 clock_gettime() 是否存在,如果可用,请使用本机实现,如果它不可用,则基于其他计时器 API 实现它。容易,对吧?我原以为这是微不足道的,所以很自然地,事实证明几乎不可能按照我想要的方式去做。;)
这是我的问题:如果我希望用户能够透明地调用clock_gettime() API,我需要我的头文件来准确检测是否存在本机声明/定义:
- 由于明显的原因,乐观检测不起作用:如果 clock_gettime() 不存在,但我的头文件的预处理器宏认为存在,它将不会被定义,并且用户会得到编译器错误。
- 保守检测更糟糕:如果存在clock_gettime并且#included但我的头文件没有检测到它,我自己的实现将与它发生冲突......而且我已经学会了编译器甚至不会抱怨clock_gettime( ) 被重新定义。相反,如果您“覆盖”现有的clock_gettime(),您的函数将被调用,有点像,但它将具有完全奇怪的未定义行为并崩溃或进入无限循环(即使您的后备实现没有任何循环)。
那么,有什么可靠的方法来检测clock_gettime()?我知道如果 clock_gettime() 存在, unistd.h 应该定义 _POSIX_TIMERS 宏......但是这对每个实现都有保证吗?(根据我的理解不是,但我可能是错的。)
- 如果是这样,我怎样才能可靠地检测 unistd.h 是否存在(它在 Windows 上不存在,至少在 MSVC 中不存在,它存在于 Linux/BSD 上,但是那里有很多次要操作系统等)?
- 如果没有,还有什么其他简单的头文件可以可靠地检测到它吗?
如果没有“自动”解决方案,是否有支持(或不支持)clock_gettime() 的所有平台的可靠、精确列表,以及它们的标识宏(对于那些不在http://sourceforge.net/p /predef/wiki/OperatingSystems/)?这并不理想,因为随着新平台的出现,列表可能会不同步,但总比没有好。
当然,我可以为我自己的小库创建一个全新的计时器 API。然后我可以保守地检测 clock_gettime() 并在必要时回退到其他后端。这是一个显而易见的解决方案,很容易工作,但是......谁想学习另一个愚蠢的计时器 API?世界真的需要一个,只是为了绕过一种没有内置机制来检测给定函数是否已经存在的语言的愚蠢性吗?;)
*理由:我为什么不直接使用 C++11 的 std::chrono?
- C++11 chrono 接口不支持进程计时器,这对于某些类型的基准测试更可取。这些计时器不会在每个平台上都可用,但我想尽最大努力使用它们,而 clock_gettime() 是支持它们的最知名的现有接口。
- 我希望这段代码在 C++03 上运行,所以无论底层语言标准或操作系统如何,我都需要一个一致的用户界面......而且我无法重新实现整个 C++11 std ::chrono 接口在没有它的平台上。那将是疯狂的。