C++11 检测C+对[[noreturn]]的支持+;编译器通过CMake还是预处理器检查?

C++11 检测C+对[[noreturn]]的支持+;编译器通过CMake还是预处理器检查?,c++11,cmake,C++11,Cmake,我正在使用一些应该同时支持C++11和C++03的代码。我想标记一个函数[[noreturn]],但由于这在C++03中不存在,我试图找出如何最好地使用预处理器符号来保护它 在此电子邮件线程中,建议尝试检查是否支持单个功能,而不是所有C++11: 托德·格里尔写道: 您可以考虑使用Boost的配置子系统的代码。这里有几十个宏的列表,它们定义这些宏来设置哪些编译器中有哪些功能: -- 托德·格里尔 Affinegy公司首席科学家 然而,我没有找到任何似乎符合我要求的东西。(在boost配置文件中

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

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

托德·格里尔写道:

您可以考虑使用Boost的配置子系统的代码。这里有几十个宏的列表,它们定义这些宏来设置哪些编译器中有哪些功能:

--
托德·格里尔
Affinegy公司首席科学家

然而,我没有找到任何似乎符合我要求的东西。(在boost配置文件中或其他地方。)


有人知道用C预处理器技巧直接实现这一点的方法吗,或者知道检测此功能的现有CMake模块吗?(如果不是的话,我想我会试着把它们混在一起。)

试试这样的方法:

#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()
{
    //...
}

您可以执行以下CMake检查:

include(CheckCXXSourceCompiles)

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

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

然后,您可以将HaseAttEtjyNoReurn传递给C++代码,并使用<代码> IFDEF < < /P> 优点是,您不会错过未设置正确的_cpluplus变量或不支持u has_属性功能的编译器


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

CMAKE_REQUIRED_标志来完成

您确定这是C++11功能吗?我认为它是一个特定于编译器的扩展。Clang有宏
\uuuu有\uCPP\u属性
,你可以用它来检查是否有可用的C++11样式属性,但话说回来,GCC不支持它。@imallett:这些家伙并不总是对的,但是他们声称它是C++11的一部分:我想我可以签入标准…我刚刚检查了GCC文档,它支持
\uuu从5.1开始就有\uCPP\u属性
:因为它是C++11中引入的标准属性,
\if\uu cplusplus>=201103L
似乎是一种非常合理的检查方法。我猜我在读了评论后想的是,就像你的评论一样,还有一个
\elif\uu cplusplus>=201103L
,因为这也应该保证符号存在,我猜,即使
\uuuu有\ucpp\u属性
也有not@ChrisBeck除非编译器声称是C++11,实际上不是。@ChrisBeck:检查
\uu cplusplus>=201103L
不能保证支持
[[noreturn]]
,特别是在不将
\uuuCPlusplus
定义为语言版本号的编译器中。这是保存答案,但您将错过不支持nice的编译器,如Microsoft的VS和一些GCC 4.x。我接受了另一个,因为这是我实际做的,但也感谢这个答案,它是有用的