【问题标题】:Detect if OS is available (e.g. std::mutex)检测操作系统是否可用(例如 std::mutex)
【发布时间】:2020-07-17 20:20:33
【问题描述】:

有没有办法通过宏来检测目标平台是否支持 std::mutex?

我想为我们的一个开源项目做出贡献,因为他们正在使用 std::mutex。我们正在使用 gcc-arm-none-eabi,其中 std::mutex 不可用(但 RTOS 特定互斥锁)。

如果我可以通过预处理器宏检测是否没有可用的操作系统,我将启用 (ifdef) 代码以提供自定义互斥锁。

我可以测试 gcc-arm-none-eabi 但由于那里还有其他“裸机”编译器,我宁愿测试功能的缺失而不是编译器/目标平台的存在.

【问题讨论】:

  • @Eljay 是的,但没有针对这种特殊情况的功能测试宏。
  • “std::mutex is not available”是指整个标头<mutex>不可用,std::mutex类未定义或存在,但不允许使用是吗?
  • @Yksisarvinen std::mutex 未定义。标头始终存在。 中的 ifdef 不可移植。

标签: c++ macros


【解决方案1】:

标准确实指定了一些可能提供帮助的预定义宏。

首先,<mutex> 是在 C++11 中引入的,因此我们可以使用预定义的宏 __cplusplus 来检测我们的实现是否声称是 C++11 或更高版本。

#if __cplusplus >= 201103L

其次,C++11 标准规定托管实现是指程序可以有多个线程同时执行的实现(与独立实现不同,在独立实现中,有多个线程同时执行的能力是实现定义)。方便的是,它还引入了一个预定义的宏 __STDC_HOSTED__ 来测试托管实现,以及一个可选定义的宏 __STDCPP_THREADS__ 来测试一个程序是否可以有多个执行线程。如果为真,则两者都扩展为 1

#if __STDC_HOSTED__ == 1 && __STDCPP_THREADS__ == 1

在大多数情况下,可以合理地假设一个不能有多个执行线程的系统不支持它们之间的同步方式。

将所有这些放在一起,我们得到(使用未定义的宏不会测试为等于1这一事实)

#if __cplusplus >= 201103L && __STDC_HOSTED__ == 1 && __STDCPP_THREADS__ == 1

#include <mutex>

//   code that uses <mutex> here


#else

// start testing for other OS and mutex/thread mechanisms here
#endif

我还没有测试过上述内容,但这是我在开始深入研究特定于特定主机系统或编译器的测试宏之前将其用作第一次切入。

【讨论】:

  • 它应该是这样工作的,但实际情况有所不同。甚至 Clang 和 GCC 也根本没有定义 __STDCPP_THREADS__ (在 linux 上)。
【解决方案2】:

您可以创建一个使用 std::mutex 的小型 c++ 源文件。如果编译失败,你可能会认为你没有std::mutex

如何在项目构建期间执行此操作并设置预处理器宏取决于您的构建系统。

【讨论】:

  • 谢谢,但这对于我不拥有的开源项目来说太复杂了,例如只是标题。
  • @Viatorus 然后,您需要使用需要为此类平台定义的任何宏和文档,以便使用该库的人将其放入他们的构建系统中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 2011-07-07
  • 2019-10-04
  • 2012-04-01
  • 2012-02-05
相关资源
最近更新 更多