C预处理程序宏-基于参数串联的条件 [英] C Preprocessor Macros - conditionals based upon argument concatenation

查看:101
本文介绍了C预处理程序宏-基于参数串联的条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要有关宏的帮助!

假设我已经定义了以下常量

Suppose I’ve got the following constants defined

#define foo_tacos_tuesday    1
#define foo_tacos            1
#define foo_nachos_wednesday 2
#define foo_nachos           3

我想编写一个执行以下操作的宏

I’d like to write a macro that does the following

#define MyFancyMacro( arg1, arg2 )                     \
     #if ( foo_ ## arg1 ## _ ## arg2 != foo_ ## arg1 ) \
         foo_ ## arg1 ## _ ## arg2, foo_ ## arg1,

因此,我可以建立一个仅映射不匹配值的映射表:

So I can set up a mapping table that only maps the mismatching values:

static const int mappingTable[] =
    {
         MyFancyMacro(tacos, tuesday)
         MyFancyMacro(nachos, wednesday)
    };

最后,mappingTable的长度应为两个整数,分别为2和3.

In the end the mappingTable should just be two ints in length, containing 2 and 3.

有什么想法吗?

谢谢.

推荐答案

您可以使用高级宏库(例如 Order-PP ,尽管缺点是其中包含了大量内容,可能会缩短编译时间,并且可移植性令人怀疑*.

You can do this with an advanced macro library like Order-PP, although the downside with that is a huge amount of included stuff, potentially slow compile times, and questionable portability*.

执行您所要求的功能可能看起来像这样:

A function to do what you ask might look something like this:

#include <order/interpreter.h>

// defining functions is a bit long-winded
#define ORDER_PP_DEF_8fancy ORDER_PP_FN( \
  8fn(8L, 8R, \
      8if( 8equal(8L, 8R), \
           8print(8space), \
           8print(8L 8comma 8R 8comma) ) ) )

// testing this
ORDER_PP (  // (execute Order code)
  8fancy(1, 1)   //should do nothing
)
ORDER_PP (
  8fancy(2, 3)   //should show 2,3,
)

// wrap up in a conventional C macro
#define MyFancyMacro(arg1, arg2) ORDER_PP( \
    8fancy( foo_ ## arg1 ## _ ## arg2, foo_ ## arg1 ) \
)

// test the full version
#define foo_tacos_tuesday    1
#define foo_tacos            1
#define foo_nachos_wednesday 2
#define foo_nachos           3
static const int mappingTable[] =
{
     MyFancyMacro(tacos, tuesday)    //nothing
     MyFancyMacro(nachos, wednesday) //2,3,
};

这是相当脆弱的-它仅适用于整数,并且如果您尝试比较其他内容,则会发出难以理解的错误消息.即使这样,幕后也需要大量宏才能启用==之类的东西(它基本上具有大量的预设宏,例如EQUAL_1_1返回1,EQUAL_1_0返回0). Order语言的局限性还意味着,对于大于99的整数,您需要使用怪异的格式.

This is pretty fragile though - it will only work with integers and will barf up an incomprehensible error message if you try to compare something else. Even that requires quite a lot of macro magic behind the scenes to enable something like == (it basically has an extremely large number of preset macros like EQUAL_1_1 returning 1 and EQUAL_1_0 returning 0). A limitation of the Order language also means you need to use a weird format for integers larger than 99.

(if本身很容易定义为宏,并且只能使用四个预处理器定义来完成-整数比较会生成布尔值,这是复杂的部分,因为您必须完全重新实现算术本身仅使用令牌替换.)

(if itself is very easy to define as a macro and can be done with only four preprocessor definitions - it's the integer comparison which generates a boolean that's the complex part, since you have to completely reimplement arithmetic itself using nothing but token substitution.)

* Order是符合标准的,多数不是编译器.

我也要注意不要使用任何宏来设计任何返回尾随逗号的宏-这很可能会使其他人(甚至在您忘记的时候,也使您感到困惑),因为语法输入"与语法输出"不再匹配.实际上,考虑到这个问题看上去就像建立一个数组,然后过滤掉值,为什么不在程序初始化期间在运行时真正做到这一点呢?

I'd also caution against designing anything with macros that return a trailing comma - that's highly likely to confuse other people (or even you, when you forget), because "syntax in" stops matching up with "syntax out". In fact given that this problem looks like building an array and then filtering values out, why not do that for real at runtime during program initialization?

这篇关于C预处理程序宏-基于参数串联的条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆