C预处理器宏 – 基于参数连接的条件
我需要有关宏的帮助!
假设我已经定义了以下常量
#define foo_tacos_tuesday 1 #define foo_tacos 1 #define foo_nachos_wednesday 2 #define foo_nachos 3
我想编写一个执行以下操作的宏
#define MyFancyMacro( arg1, arg2 ) \ #if ( foo_ ## arg1 ## _ ## arg2 != foo_ ## arg1 ) \ foo_ ## arg1 ## _ ## arg2, foo_ ## arg1,
所以我可以设置一个只映射不匹配值的映射表:
static const int mappingTable[] = { MyFancyMacro(tacos, tuesday) MyFancyMacro(nachos, wednesday) };
最后,mappingTable的长度应为两个整数,包含2和3。
知道怎么做吗?
谢谢。
您无法将C预处理器宏扩展为预处理器语句。 但是,您可以使用文件包含来实现解决方法。
想象一下,你有一个名为mh
的头文件,其中包含以下内容:
#ifndef MY_FANCY_HEADER #define XFOO2(arg1, arg2) foo_ ## arg1 ## _ ## arg2 #define FOO2(arg1, arg2) XFOO2(arg1, arg2) #define XFOO(arg1) foo_ ## arg1 #define FOO(arg1) XFOO(arg1) #endif #define FOO_ARG1_ARG2 FOO2(ARG1, ARG2) #define FOO_ARG1 FOO(ARG1) #if FOO_ARG1_ARG2 != FOO_ARG1 FOO_ARG1_ARG2, FOO_ARG1, #endif #undef ARG1 #undef ARG2 #undef FOO_ARG1_ARG2 #undef FOO_ARG1
然后,在源文件中,您可以执行以下操作:
static const int mappingTable[] = { #define ARG1 tacos #define ARG2 tuesday #include "mh" #define ARG1 nachos #define ARG2 wednesday #include "mh" };
我承认它并不理想,但由于你无法将宏扩展为预处理器语句,我相信这是使用标准C预处理器实现它的唯一方法。
您可以使用像Order-PP这样的高级宏库来实现这一点,尽管其缺点是包含大量内容,可能会导致编译时间变慢,以及可疑的可移植性*。
做你要求的function可能看起来像这样:
#include // 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的整数使用奇怪的格式。
( if
它本身非常容易定义为一个宏,并且只能用四个预处理器定义来完成 – 它是整数比较,它生成一个复杂部分的布尔值,因为你必须完全重新实现算术本身,只使用令牌替换。)
*订单符合标准,大多数编译器都不符合标准。
我还提醒我不要设计任何带有返回逗号的宏 – 这很可能会让其他人(甚至是你,当你忘记时)混淆,因为“语法”会停止与“语法输出”匹配。 事实上,鉴于此问题看起来像构建一个数组然后过滤掉值,为什么不在程序初始化期间在运行时实现呢?