替换子宏中的父标记
Substitute parent tokens in child macro
我正在寻找替换被调用宏中的一些标记,但似乎无法确定扩展 and\or 延迟的正确顺序。例如:
#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()
的许多不同组合,但 none 似乎给出了我想要的结果。
有没有人知道我做错了什么?
这不是处理宏参数的方式,这是有原因的。如果宏参数中宏参数名的使用可以被替换,那么就不可能编写安全的宏:不小心使用宏参数名会造成混乱,宏调用者没有理由需要知道参数的名称是什么。宏参数对于宏展开是局部的,类似于函数参数对于函数体是局部的。
这是实际的替换算法,来自 C 标准的 §6.10.3.1/1 [Argument Substitution]:
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list… is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
请注意,在 放入宏扩展之前,参数被宏替换 。完成后,替换列表中的参数名称不再相关,并且不属于替换文本的一部分。
一旦宏调用被其扩展替换,生成的标记将被再次扫描(§6.10.3.4:"The resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.")。但是,由于在此重新扫描之前已完全替换宏调用,因此不再出现参数标记。
所以这个针对您问题的特定解决方案是死路一条。我建议您后退一步,专注于您真正希望解决的问题。
我正在寻找替换被调用宏中的一些标记,但似乎无法确定扩展 and\or 延迟的正确顺序。例如:
#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()
的许多不同组合,但 none 似乎给出了我想要的结果。
有没有人知道我做错了什么?
这不是处理宏参数的方式,这是有原因的。如果宏参数中宏参数名的使用可以被替换,那么就不可能编写安全的宏:不小心使用宏参数名会造成混乱,宏调用者没有理由需要知道参数的名称是什么。宏参数对于宏展开是局部的,类似于函数参数对于函数体是局部的。
这是实际的替换算法,来自 C 标准的 §6.10.3.1/1 [Argument Substitution]:
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list… is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
请注意,在 放入宏扩展之前,参数被宏替换 。完成后,替换列表中的参数名称不再相关,并且不属于替换文本的一部分。
一旦宏调用被其扩展替换,生成的标记将被再次扫描(§6.10.3.4:"The resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.")。但是,由于在此重新扫描之前已完全替换宏调用,因此不再出现参数标记。
所以这个针对您问题的特定解决方案是死路一条。我建议您后退一步,专注于您真正希望解决的问题。