Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.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++ 如何在GCC中弃用C预处理器宏?_C++_C_Gcc_Macros_Deprecated - Fatal编程技术网

C++ 如何在GCC中弃用C预处理器宏?

C++ 如何在GCC中弃用C预处理器宏?,c++,c,gcc,macros,deprecated,C++,C,Gcc,Macros,Deprecated,我知道如何使用\uuuu attribute\uuuu((已弃用))或[[deprecated]]来弃用这样的函数: int old_fn() __attribute__ ((deprecated)); [[deprecated]] int old_fn2(); #define OLD_MACRO 1 #ifdef USE_DEPRECATED_MACROS #warning using deprecated macros #define OLD_MACRO 1 ... #endif 但是

我知道如何使用
\uuuu attribute\uuuu((已弃用))
[[deprecated]]
来弃用这样的函数:

int old_fn() __attribute__ ((deprecated));
[[deprecated]] int old_fn2();
#define OLD_MACRO 1
#ifdef USE_DEPRECATED_MACROS
#warning using deprecated macros
#define OLD_MACRO 1
...
#endif
但是如何弃用这样的宏:

int old_fn() __attribute__ ((deprecated));
[[deprecated]] int old_fn2();
#define OLD_MACRO 1
#ifdef USE_DEPRECATED_MACROS
#warning using deprecated macros
#define OLD_MACRO 1
...
#endif

由于宏不是编译器的一部分(它们是预处理器函数),因此没有干净的方法来实现这一点。最好将不推荐使用的宏放在一个新的头文件中,该头文件中填充了#警告。这当然会破坏现有的代码,但这是一种保证引起注意的方法。

我认为最好的方法是这样:

int old_fn() __attribute__ ((deprecated));
[[deprecated]] int old_fn2();
#define OLD_MACRO 1
#ifdef USE_DEPRECATED_MACROS
#warning using deprecated macros
#define OLD_MACRO 1
...
#endif

通过这种方式,您可以强制用户将-DUSE\u DEPRECATED\u宏添加到他们的编译器选项中,然后他们会收到警告。

您可以确保这些宏将扩展到包含表达式的内容,该表达式将触发
\u属性((DEPRECATED))
警告

对于类似函数的宏,这非常容易(特别是使用逗号运算符),但对于常量定义或非标准宏,这可能更复杂,因为这些宏展开的上下文不同。 我想你可以做到:

#define DEPRECATE(name) static inline void __attribute__((deprecated)) deprecate_ ## name (void) { ; }
...
#define MAX(x, y) (DEPRECATE(MAX), x>y?x:y)
// yeah, yeah, it repeats args in the body, but it's just an example
对于常量定义,您可能希望假定主体必须求值,而不必生成代码,例如在函数主体外部、开关/案例的目标中或作为函数中静态变量的初始值

这是个棘手的问题,但是你可以做很多事情

我希望C有一个
\uuu内置警告(const char*)
,它可以在编译器级别(而不是预处理器)工作,并使类似的事情变得更容易

对于常量定义,您可以执行以下操作:

#define THREE (DEPRICATED(THREE),3)

漂亮、优雅的解决方案,但取决于C99是否启用(适用于gcc 4.8.2或更高版本,未在早期版本上测试):


作为一种品味,我更希望在
#include
之前在源代码中让用户
#define USE#u DEPRECATED#u MACROS 1
,而不是通过命令行输入标志。。。但事实上,无论哪种方式,结果都是一样的;他们必须知道自己在做什么,并在可能的情况下放弃(从而失去警告)。好球!我会用另一种方法:
#如果没有不推荐的宏
。这样,您可以在保持头文件客户端的源代码兼容性的同时发出警告。然后,用户可以添加
NO_DEPRECATED_MACROS
,以消除警告,而不是在获取新头文件时破坏其构建,并且他必须阅读发行说明以找出旧_MACROS消失的原因。当然,如果用户使用
-Werror
这一切都是一样的,但如果他不这样做,那么可能正是因为他不希望自己的构建因为你在修补警告而倒塌;-)这不会告诉用户正在使用哪个已弃用的宏/他应该用什么替换哪些宏等等。事实上,如果你有那个宏,你就需要弃用它。@Joshua:在下一版本的软件中,不会定义
THREE
,但在之后的版本中,
定义THREE(4)
。“在C99中,函数“DEPRICATED”的隐式声明无效。如果我使用
DEPRECATE
,我会得到“Expected expression”。这在gcc 4.3.3中似乎不起作用。不过这是一个不错的选项。@mjs根据,
\u Pragma
应该从gcc 3.0开始支持(从gcc 4.5开始完全支持C99)。在4.5之前,您可能必须使用
-std=C99
显式启用C99(可能更晚,不知道C99何时获得gcc标准…)为了让它发挥作用。@Aconcagua我想,_Pragma是被认可的,它只是不理解内容。但我可能错了。@mjs要想知道它是否理解内容,请尝试
#Pragma GCC warning“'DEPRECATED_MACRO1'macro is DEPRECATED”
。这就是
_Pragma
东西的等价之处。。。