我有这段代码(实际上是垃圾收集 Forth 系统解释器的一部分):
#define PRIMITIVE(name) \
do \
{ \
VocabEntry* entry = (VocabEntry*)gc_alloc(sizeof(VocabEntry)); \
entry->code = name; \
entry->name = cstr_to_pstr(#name); \
entry->prev = latest_vocab_entry; \
latest_vocab_entry = entry; \
} \
while (false)
PRIMITIVE(dup);
PRIMITIVE(drop);
PRIMITIVE(swap);
// and a lot more
但有一个问题:在行中
entry->name = cstr_to_pstr(#name);
the name
字段被替换为dup
, drop
, swap
,以及其余的。我希望字段名称不被替换。
那么,除了简单地重命名宏参数之外,还有什么方法可以解决这个问题吗?
要获得答案,请解释一般情况下是否有一种方法可以抑制宏体中宏参数名称的替换。不要回答“就这样做吧”(请)。
吉姆·巴尔特 https://stackoverflow.com/users/544557/jim-balter提供了这个解决方案一条评论 https://stackoverflow.com/questions/18167990/suppress-c-macro-variable-substitution/18168204?noredirect=1#comment135886130_18168204: 改变name
在宏替换列表中na##me
。连接运算符导致其被替换为name
,但是这是在扫描宏参数名称之后发生的,因此它不会在该扫描中被替换。其代码是:
#define PRIMITIVE(name) \
do \
{ \
VocabEntry* entry = (VocabEntry*)gc_alloc(sizeof(VocabEntry)); \
entry->code = name; \
entry->na##me = cstr_to_pstr(#name); \
entry->prev = latest_vocab_entry; \
latest_vocab_entry = entry; \
} \
while (false)
我原来的答案有点麻烦:
您可以定义不同的宏来扩展为name
, 像这样:
#define Name name
并改变name
领域中的PRIMITIVE
宏来使用新宏,如下所示:
#define PRIMITIVE(name) \
do \
{ \
VocabEntry* entry = (VocabEntry*)gc_alloc(sizeof(VocabEntry)); \
entry->code = name; \
entry->Name = cstr_to_pstr(#name); \
entry->prev = latest_vocab_entry; \
latest_vocab_entry = entry; \
} \
while (false)
除了在宏体中使用与参数名称不同的内容或更改参数名称之外,在 C 语言中没有其他方法可以做到这一点。根据 C 2011 (N1570) 6.10.3.1 1,当识别出类似函数的宏时,参数名称将立即被替换,除非#
or ##
存在,并且没有其他例外:
在确定了调用类似函数的宏的参数后,将进行参数替换。替换列表中的参数,除非前面有 # 或 ## 预处理标记或后面有 ## 预处理标记(见下文),否则在其中包含的所有宏都已展开后将被相应的参数替换。
The #
token 将参数名称更改为字符串,在这种情况下没有用。这##
token 扩展参数名称并将其与相邻标记粘贴在一起,这在这种情况下也是没有用的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)