如何重命名C预处理器宏?

考虑一个(只读第三方)头lib.h

 #define XYZ 42 

在源文件中,我想将XYZ这个词用于不相关的目的,并且不希望用42替换。 但是,在同一个源文件中,出于其他目的,我也想从lib.h访问值42而不lib.h进行硬编码。 如何将宏从XYZ 重命名LIB_XYZ

以下方法不起作用,因为预处理器LIB_XYZ替换时需要XYZ ,但XYZ未定义:

 #include "lib.h" #define LIB_XYZ XYZ #undef XYZ 

有没有办法欺骗预处理器在XYZ丢失之前将LIB_XYZ扩展到其最终值?

不是预处理器,至少不是我所知道的。

但是,对于具有已知类型的简单常量(如示例),有一种解决方法。

 #include  //  #define XYZ 42 //  enum xyz_constants { LIB_XYZ = XYZ, }; #undef XYZ #define XYZ 27 int main() { printf("old value: %d, new value: %d\n", LIB_XYZ, XYZ); return 0; } 

没有显示stdio.h的绒毛,此代码已预处理到以下内容。

 enum xyz_constants { LIB_XYZ = 42, }; int main() { printf("old value: %d, new value: %d\n", LIB_XYZ, 27); return 0; } 

您可以在某种程度上将其扩展到其他数据类型和某些类似函数的宏,但当然有限制。

无论如何,为什么你需要特定的标识符XYZ ? 你不能为你的宏使用不同的名称吗?

如果lib.h中的XYZ数字 [或lib.h的常量],则可以使用enum

 enum { LIB_XYZ = XYZ }; #undef XYZ 

如果XYZ 不是上述,你必须创建(例如) 包含lib.h并在那里使用XYZ (其他文件可能包含xyz.h

不同之处在于,只有在以后使用时才会在该行解析#define LIB_XYZ XYZ ,如:

 foo(LIB_XYZ); 

所以这不会起作用,因为你已经#undef'ed XYZ

使用另一个.c文件,并将宏值分配给全局变量。

预处理器符号名称。 没有预处理指令可以更改名称本身,同时保留内容。 例如,给定:

 #define FOO 42 

要么

 #define FOO(x, y) x ## y ( 

没有办法定义一个名为BAR的宏,它具有相同的内容,而不重复这些定义。 也就是说,没有像以下那样的操作:

 #alias BAR FOO // nonexistent fantasy macro-cloning preprocessor directive 

也不是这样的:

 #rename BAR FOO // like #alias BAR FOO followed by #undef FOO 

如果我们这样做:

 #define BAR FOO // for the #define FOO 42 case 

它不是别名。 定义宏BAR使得其替换令牌序列是令牌FOO ,而不是42 。 如果FOO宏消失,那么BAR失去了意义。

另请注意,C预处理器宏无法扩展到预处理指令,因此以下方法也不起作用

  // wrong: #define MACRO_DEFINER(NAME) \ #define NAME 42 MACRO_DEFINER(FOO) // hoping for #define FOO 42: no such luck MACRO_DEFINER(BAR) // hoping for #define BAR 42: likewise 

我担心你必须退一步才能找到一个替代策略来解决你想要解决的任何问题。 如果您遇到问题,请创建一个有关实际问题的新问题。

始终存在代码生成:在构建时生成C或C ++。 如果您只是调整您的生成系统,那么您可以梦想的任何文本替换或扩展都是可能的。