想象一下,我希望#define
一个宏,使其等于另一个宏的当前值(如果存在这样的概念)。
例如:
#include "def_a.h" // defines macro A
#define B A
这将B
定义为A
。如果A
稍后更改定义(即通过重新定义),则B
的值也会发生变化(因为B
在使用时会扩展为A
,这会进一步扩展到A
)的新值。
我想要的是某种方式将A
的价值“加入”B
,以便B
只扩展为A
的值,而不是A
本身。
例如:
#define A first
#define B BAKE_IN(A)
#undef A
#define A second
#define C BAKE_IN(A)
#undef A
#define A third
// here I want B to expand to first, and C to expand to second
当然BAKE_IN
不是真的,但我想知道是否有办法达到这个效果。
现在,我并没有真正说明如果A本身是用其他宏来定义会发生什么,但我可以用“一级扩展”(即B得到A的值扩展,所以进一步的宏仍然是“完全扩展”(即A完全展开,递归,就像在使用点一样)。
答案 0 :(得分:1)
宏在#define
指令的主体中永远不会被替换,所以没有办法将宏定义为另一个宏的当前值,除了宏的有限情况,其值是一个常量算术表达式
在后一种情况下,您可以使用Boost preprocessor library.中的BOOST_PP_ASSIGN_SLOT
(尽管大多数Boost库都是特定于C ++的,但Boost预处理器库适用于C和C ++,并且没有依赖性在任何其他Boost组件上。)
答案 1 :(得分:1)
我认为没有一个干净的解决方案。我发现最接近的事情是在char
数组中保留“字符串化”值:
#include <stdio.h>
#define BAKE_IN(X, id) BAKE_IN_REAL(X ## _, X, id)
#define BAKE_IN_REAL(X, Y, id) static const char X ## id[] = #Y;
#define BAKE_OUT(X, id) X ## _ ## id
#define A first
BAKE_IN(A, 1)
#define B BAKE_OUT(A, 1)
#undef A
#define A second
BAKE_IN(A, 2)
#define C BAKE_OUT(A, 2)
#undef A
int main(void)
{
printf("%s\n", B); // prints "first"
printf("%s\n", C); // prints "second"
return 0;
}
这个想法是BAKE_IN
宏声明对象命名为例如A_1
,其中包含A
的当前扩展。
有两个主要限制:
BAKE_IN
和BAKE_OUT
都需要唯一ID