在子宏中替换父令牌

问题描述 投票:0回答:1

我想在一个被调用的宏中替换一些令牌,但似乎无法确定扩展和\或延迟的正确顺序。例如:

#define EXPAND(...) __VA_ARGS__
#define REPLACE(hello,y) EXPAND(y)
REPLACE(goodbye, hello world)

在我看来,REPLACE宏将调用EXPAND宏,使其功能相同:

#define REPLACE(hello,y) hello world

允许hello world转变为goodbye world

我的编译器(MSVC 2017)似乎没有这样做,所以我怀疑我在这里错了。我已经阅读了扩展和推迟,并尝试了许多不同的DEFER()EXPAND()组合,但似乎都没有给出我追求的结果。

有没有人对我做错了什么有任何见解?

c macros c-preprocessor preprocessor
1个回答
0
投票

这不是宏参数的处理方式,也不是原因。如果可以替换在宏的参数中使用宏参数名,那么就不可能编写安全的宏:不小心使用宏参数的名称会导致混乱,并且没有理由为什么宏调用者需要知道参数的名称是什么。宏参数是宏扩展的本地参数,类似于函数体的本地函数参数的方式。

这是C标准的§6.10.3.1/ 1 [Argument Substitution]中的实际替换算法:

在确定了调用类函数宏的参数之后,发生了参数替换。在扩展了包含在其中的所有宏之后,替换列表中的参数...被相应的参数替换。在被替换之前,每个参数的预处理标记都被完全宏替换,好像它们形成了预处理文件的其余部分;没有其他预处理令牌可用。

请注意,在放入宏扩展之前,参数是宏替换的。完成后,替换列表中的参数名称不再相关,并且不是替换文本的一部分。

一旦宏调用被其扩展替换,然后再次扫描生成的标记(第6.10.3.4节:“然后重新扫描生成的预处理标记序列,以及源文件的所有后续预处理标记,以获得更多的宏名称更换。”)。但是,由于在此重新扫描之前已完全替换宏调用,因此不再显示参数标记。

所以这个问题的特殊解决方案是一个死胡同。我建议您备份一个步骤并专注于您实际想要解决的问题。

© www.soinside.com 2019 - 2024. All rights reserved.