C++ __具有非';功能类似于';宏?
我正试图将C++ __具有非';功能类似于';宏?,c++,gcc,macros,c++14,C++,Gcc,Macros,C++14,我正试图将[[deprecated]]属性引入我的代码库。但是,并不是所有我需要支持的编译器都支持这种语法(不同编译器在标准化之前使用的各种方法在中进行了描述)。因此,我尝试在该属性中有条件地编译,首先使用类宏函数\uu has\u cpp\u attribute,如果可用,如下所示: #if defined(__has_cpp_attribute) && __has_cpp_attribute(deprecated) #define DEPRECATED(msg) [[
[[deprecated]]
属性引入我的代码库。但是,并不是所有我需要支持的编译器都支持这种语法(不同编译器在标准化之前使用的各种方法在中进行了描述)。因此,我尝试在该属性中有条件地编译,首先使用类宏函数\uu has\u cpp\u attribute
,如果可用,如下所示:
#if defined(__has_cpp_attribute) && __has_cpp_attribute(deprecated)
#define DEPRECATED(msg) [[deprecated(msg)]]
#elif OTHER_COMPILER
// ...
#endif
但是,当我使用gcc版本4.9.2(gcc),命令行gcc-std=c++14 cpp.cpp时,我在编译此文件时遇到了错误:
cpp.cpp:1:56: error: missing binary operator before token "("
#if defined(__has_cpp_attribute) && __has_cpp_attribute(deprecated)
此错误似乎表明已定义了\uuu has\u cpp\u属性
,但它不是宏函数。有条件地编译gcc中的[[deprecated]]
属性的正确方法是什么?gcc 4.9没有\uuuuu有\uCPP\u属性
,并且&
的短路行为不会扩展到允许无效构造跟随它
也就是说,如果没有定义foo
#if defined(foo) && foo(bar)
无效
你想要的是
#if defined(__has_cpp_attribute)
#if __has_cpp_attribute(deprecated)
#define DEPRECATED(msg) [[deprecated(msg)]]
#endif
#elif OTHER_COMPILER
// ...
#endif
因此,如果未定义\uuuuuuuuuuuuuuuuuuuuuuu has\ucpp\u attribute
,则将跳过使用\uuuuuuuhas\ucpp\u attribute
的条件。(在被跳过的组中,预处理指令只通过指令的名称进行处理;其余的令牌被忽略。)T.C.的答案是正确的,我想补充一点,您还可以为\uu has\uCPP\u属性
定义包装器,这会使多个测试更容易编写
#if defined(__has_cpp_attribute)
# define MY_HAS_CPP_ATTRIBUTE(attr) __has_cpp_attribute(attr)
#else
# define MY_HAS_CPP_ATTRIBUTE(attr) (0)
#endif
#if MY_HAS_CPP_ATTRIBUTE(attr)
# define MY_DEPRECATED [[deprecated(msg)]]
#else
# define MY_DEPRECATED
#endif
如果您这样做,请使用名称空间,而不是定义\uuuu具有\ucpp\u属性
。其他代码将检查是否定义了(\uuu有\ucpp\u属性)
,如果可用,则使用它,如果没有,则返回检查编译器版本。定义\uuuu具有\ucpp\u属性将打破这一点
当然,许多其他编译器支持某种语法,用于将符号标记为不推荐使用的符号,即使它们不支持\uuuu有\ucpp\u属性
,因此您可能会遇到更多的情况;请参阅中的HEDLEY\u已弃用宏。它目前支持GCC 4.5+、ICC 13+、armcc 4.1+和TI 7.3+使用不推荐的属性,MSVC 13.10+和Pelles 6.50+使用不推荐的declspec,IAR使用pragma,但支持可能会随着时间的推移而扩展,我可能不会更新这个答案。@t.C.Oh,它没有功能测试宏?@Columbo我在gcc 5.1发行说明中看到:,它说添加了\u has\u cpp\u属性
;所以我想在那之前它是不存在的。