在#define中#ifdef的逻辑实现

时间:2014-05-09 12:51:57

标签: c c-preprocessor

这段代码中有没有办法

#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

有没有办法得到类似的东西?

3 个答案:

答案 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)

不优雅。

首先,宏无法扩展到预处理程序指令。每个指令必须在顶层可见,没有任何扩展(除其他外,它在语法上是不可能的,因为没有多行宏 - \ 转义换行符,而不是包括它 - 和指令依赖新行作为语法的一部分。)

可以在宏中进行条件扩展(请参阅herehere等)。但这些都是基于扩展到布尔值的宏(或者至少可以替代布尔值)。遗憾的是defined是一个运算符而不是宏,这意味着它只能出现在预处理器表达式中,即#if指令的参数。它不能扩展到任何可以插入到程序体中的东西,因此不能构成依赖于扩展来选择动作的宏定义的一部分。

如果你真的想要一个静态的if宏,那么总是定义t1t2等(选择在两个可能的值之间而不是在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约定(函数,大写,范围等)