Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ __具有非';功能类似于';宏?_C++_Gcc_Macros_C++14 - Fatal编程技术网

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属性
;所以我想在那之前它是不存在的。