【问题标题】:Detect [[noreturn]] support by C++ compiler via CMake or preprocessor checks?通过 CMake 或预处理器检查检测 C++ 编译器对 [[noreturn]] 的支持?
【发布时间】:2015-11-04 00:56:07
【问题描述】:

我正在处理一些应该支持 C++11 和 C++03 的代码。我想标记一个函数[[noreturn]],但由于它在 C++03 中不存在,我试图找出如何最好地用预处理器符号保护它。

在此电子邮件线程中,建议尝试检查是否支持单个功能而不是所有 C++11:

https://cmake.org/pipermail/cmake/2013-February/053635.html

托德·格里尔写道:

您可以考虑使用来自 Boost 配置子系统的代码。他们定义了几十个宏的列表,用于设置哪些编译器可以使用哪些功能:http://www.boost.org/doc/libs/1_53_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported

--
托德·格里尔
Affinegy, Inc. 首席科学家

但是,我没有找到任何似乎可以做我想做的事情。 (在 boost 配置文件中,或其他地方。)

有没有人知道直接使用 C 预处理器技巧来执行此操作的方法,或者知道检测此功能的现有 CMake 模块? (如果没有,我想我会尝试拼凑一个。)

【问题讨论】:

  • 你确定这是 C++11 的特性吗?我认为这是一个特定于编译器的扩展。
  • Clang 有宏 __has_cpp_attribute,您可以使用它来检查 C++11 样式的属性是否可用,但是 AFAIK,GCC 不支持它。
  • @imallett:这些人并不总是正确的,但他们声称这是 C++11 的一部分:en.cppreference.com/w/cpp/language/attributes 我想我可以检查一下标准...
  • 我刚刚查看了 GCC 文档,它从 5.1 开始支持 __has_cpp_attributegnu.org/software/gcc/gcc-5/changes.html
  • 由于它是 C++11 中引入的标准属性,#if __cplusplus >= 201103L 似乎是一种非常合理的检查方式。

标签: c++11 cmake


【解决方案1】:

试试这样的:

#ifdef __has_cpp_attribute
#  if __has_cpp_attribute(noreturn)
#    define NO_RETURN [[noreturn]]
#  else
#    define NO_RETURN
#  endif
#else
#  define NO_RETURN
#endif

NO_RETURN void myFunc()
{
    //...
}

【讨论】:

  • 我猜我在阅读 cmets 后想的是,就像你所拥有的一样,还有一个 #elif __cplusplus >= 201103L,因为这也应该保证我猜该符号存在,即使 __has_cpp_attribute 确实存在不是
  • @ChrisBeck 除非编译器声称是 C++11,但实际上并非如此。
  • @ChrisBeck:检查__cplusplus >= 201103L 并不能保证支持[[noreturn]],尤其是在没有将__cplusplus 定义为语言版本号的编译器中。
  • 这是保存的答案,但你会错过不支持他很好的 __has_cpp_attribute 的编译器,比如微软的 VS 和一些 GCC 4.x。
【解决方案2】:

您可以执行以下 CMake 检查:

include(CheckCXXSourceCompiles)

check_cxx_source_compiles("
   [[noreturn]] void testFunc()
   {}

   int main(void)
   {
     return 0;
   }
"  HAS_ATTRIBUTE_NORETURN
)

然后,您可以将 HAS_ATTRIBUTE_NORETURN 传递给 your config.h,并在您的 C++ 代码中使用 ifdef

优点是,您不会错过未设置正确 _cpluplus 变量或不支持 __has_attribute 功能的编译器。

根据您的设置,您可能需要添加标志来设置 C++ 模式(如 -std=c++11 或 c++0x)。这可以通过 CMakePushCheckState 和修改 CMAKE_REQUIRED_FLAGS 来完成。

【讨论】:

  • 我接受了另一个,因为这是我实际所做的,但也感谢这个答案,它很有帮助
猜你喜欢
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多