我需要帮助宏!
假设我已经定义了以下常量
#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。
知道怎么做吗?
感谢。
答案 0 :(得分:1)
您无法将C预处理器宏扩展为预处理器语句。但是,您可以使用文件包含来实现解决方法。
想象一下,您有一个名为m.h
的头文件,其中包含以下内容:
#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 "m.h"
#define ARG1 nachos
#define ARG2 wednesday
#include "m.h"
};
我承认它并不理想,但由于你无法将宏扩展为预处理器语句,我相信这是使用标准C预处理器完成它的唯一方法。
答案 1 :(得分:1)
你可以使用像Order-PP这样的高级宏库来做到这一点,虽然它的缺点是包含大量内容,可能会缩短编译时间,并且可疑的可移植性*。
执行您所要求的功能可能看起来像这样:
#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的整数使用奇怪的格式。
(if
本身非常容易定义为宏,并且只能使用四个预处理器定义来完成 - 它是整数比较,它生成一个复杂部分的布尔值,因为你必须完全重新实现算术本身只使用令牌替换。)
*订单符合标准,大多数编译器都没有。
我还提醒我不要设计任何带有返回逗号的宏 - 这很可能会让其他人(甚至是你,当你忘记时)混淆,因为“语法”会停止与“语法输出”匹配。事实上,鉴于这个问题看起来就像构建一个数组然后过滤掉了值,为什么不在程序初始化期间在运行时实现呢?