基于宏参数的预编译时决策

时间:2012-09-03 20:09:39

标签: c macros c-preprocessor

我有这个宏将事件发布到某个事件队列。

POST_(myTarget, event)

事件可以直接发布到本地队列,也可以序列化并发布到I2C服务的事件队列,该服务将事件发送到另一个微控制器。接收服务是本地还是远程服务定义如下:

#define myTarget_REMOTE
#define anotherTarget_LOCAL

我想做的是这样的事情(当然不允许):

#define POST(target, e) \
    #ifdef target##_REMOTE \
        /* create a i2c request-event with serialized(e) 
           as parameter and post to I2c-Manager */
    #else \
        /* post directly */
        POST_(target, event) \
    #endif

因此,所有信息都在编译时出现,但我不知道如何告诉预处理器该做什么。

  • 我可以为每个目标创建两个宏,具体取决于它的本地/远程定义,但这会很混乱。
  • 我可以在运行时进行测试,但这也是一个悲伤的故事。

编辑:

程序看起来更清晰的一个例子:

#define target1_LOCAL
#define target2_REMOTE

POST(target1, e) ==preprocessor==> POST_(target1, e)

POST(target2, e) ==preprocessor==> 
    do { \
        req = createI2cRequest(serialize(e)); \
        POST_(I2cManager, req); \
    }while(0)

所以,在程序中我只使用POST(target, event),目标的位置是完全透明的。

4 个答案:

答案 0 :(得分:1)

宏内部的条件编程有点棘手,但可以使用C99。在P99中,我编写了一系列有条件的条件,可以在这里提供帮助。

#define myTarget_TYPE 0
#define anotherTarget_TYPE 1

#define POST(target, e)                                   \
    P99_IF_EQ_1(P99_PASTE2(target, _TYPE))                \
      (                                                   \
        /* create a i2c request-event with serialized(e)  \
           as parameter and post to I2c-Manager */        \
      )(                                                  \
        /* post directly */                               \
        POST_(target, event)                              \
      )

诀窍是你应该每个目标都有一个宏。对于那些您想要第一个替代品的人,您可以使用令牌1。您甚至可以省略将其他人声明为0

一般形式类似于

P99_IF_COND( /* expression(s) for condition */ )(/* case true */)(/* case false*/)

你可以用上面的COND做很多事情,测试与特定标记的相等性,十进制数的相等性,参数列表的空白......

答案 1 :(得分:1)

所以我终于明白了。 诀窍是使用预处理器为编译器提供所有需要的信息,并依赖编译器来优化if / else。

#define REMOTE  1
#define LOCAL   0

#define TARGET0_LOCATION REMOTE
#define TARGET1_LOCATION LOCAL

#define TEST(target) do { \
        if(target##_LOCATION == REMOTE) printf("REMOTE\n"); \
        else printf("LOCAL\n"); \
    }while(0)

main(){
    TEST(TARGET0);
    TEST(TARGET1);
}

输出:

REMOTE
LOCAL

答案 2 :(得分:0)

将一些定义拉出来: -

#ifdef I2C
#define TARGETFUNC _REMOTE
#else
#define TARGETFUNC _LOCAL
#endif
#define POST(target, e) POST(target##TARGETFUNC,e)

答案 3 :(得分:0)

#define post_myTarget(x)       remote_post(x)
#define post_anotherTarget(x)  local_post(x)

#define POST(target, e) post_##target(e)