这段代码中有没有办法
#include <stdio.h>
// #define t1
#define msg_a 1
#define msg_b 2
#define msg_c 3
#ifdef t1
#define msg_d 4
#define msg_e 5
#endif
#define call(msg) case msg_ ## msg: printf("msg_" #msg); break;
#define avail \
call(a) \
call(b) \
call(c) \
call(d) \
call(e) \
int main(void)
{
int test;
test = 2;
printf("test = %d\n", test);
switch (test)
{
avail
}
printf("\nend\n");
return 0;
}
获得(逻辑上)与波纹管代码相同的结果?
#define avail \
call(a) \
call(b) \
call(c)
#ifdef t1
call(d) \
call(e) \
#endif
因此,如果case msg_b: printf("msg_" "b"); break;
未定义,我不想在switch
内生成t1
等代码。
此外,可能包含更多这样的定义,然后会有
...
#ifdef t2
#define msg_f 6
#define msg_g 7
#endif
...
再次,这应该像这样
#define avail \
call(a) \
call(b) \
call(c)
#ifdef t1
call(d) \
call(e) \
#endif
#ifdef t2
call(f) \
call(g) \
#endif
有没有办法得到类似的东西?
答案 0 :(得分:0)
一种直截了当的方式:
#ifdef t1
#define avail call(a); call(b); call(c); call(d); call(e);
#else
#define avail call(a); call(b); call(c);
#endif
所以你可以扩展它来获得:
#ifdef t1
#define T1 call(d); call(e);
#else
#define T1
#endif
#ifdef t2
#define T2 call(f); call(g);
#else
#define T2
#endif
#define avail call(a); call(b); call(c); T1 T2
答案 1 :(得分:0)
不优雅。
首先,宏无法扩展到预处理程序指令。每个指令必须在顶层可见,没有任何扩展(除其他外,它在语法上是不可能的,因为没有多行宏 - \
转义换行符,而不是包括它 - 和指令依赖新行作为语法的一部分。)
您可以在宏中进行条件扩展(请参阅here,here等)。但这些都是基于扩展到布尔值的宏(或者至少可以替代布尔值)。遗憾的是defined
是一个运算符而不是宏,这意味着它只能出现在预处理器表达式中,即#if
指令的参数。它不能扩展到任何可以插入到程序体中的东西,因此不能构成依赖于扩展来选择动作的宏定义的一部分。
如果你真的想要一个静态的if宏,那么总是定义t1
,t2
等(选择在两个可能的值之间而不是在define和undefined之间),并使用其中一个链接问题中的其他静态技术。或者更好的是,重新考虑对静态的需求(在大多数情况下,最好使用C级if
语句并让编译器优化掉死分支。
答案 2 :(得分:0)
我不确定你要用这个来完成什么,所以我真的不知道这是一个好主意,但是......
#ifdef t1
#define t1_calls call(d) \
call(e)
#else
#define t1_calls
#endif
#ifdef t2
#define t2_calls call(f) \
call(g)
#else
#define t2_calls
#endif
#define avail t1_calls t2_calls
顺便提一下,我认为这只是为了表明你的意思,你知道关于宏的常规C约定(函数,大写,范围等)