How can I guarantee full macro expansion of a parameter before paste?(如何保证粘贴前参数的完整宏扩展?)
问题描述
我有一个通用宏:
#define mSwitch( Root, Case ) Root##_Case_##Case
#define mSpecialDisplay( what, Val ) mSwitch(mSpecialDisplay,what)(Val)
#define mSpecialDisplay_Case_Int(Val) ...do stuff
#define mSpecialDisplay_Case_Float(Val) ...do stuff
...more special cases
如何保证变量 Case
在粘贴到 mSwitch
之前完全展开?
how do I guarantee that the variable Case
is fully expanded before it gets pasted in mSwitch
?
如果向 mSwitch
传递一个文字值,它会正常工作,但如果有多层间接或中间操作,mSwitch 最终会在它们完全展开之前粘贴其中一层.
It works fine if mSwitch
is passed a literal value, but if there are several layers of indirection, or intermediary operations, mSwitch ends up pasting one of those before they get fully expanded.
我正在使用 MSVC 2005
.
有没有一种简单的方法可以确保参数在粘贴完成之前完全展开?
Is there a simple way to make sure a parameter is fully expanded before pasting is done?
谢谢
好吧,举个例子也许并不难:
well, it isn't that hard to give an example maybe:
#define mMDebugInfo( ... ) mMDebugExp( mMDebugInfo_( 0, __VA_ARGS__ ) )
#define mMDebugInfo_( C, ... ) mMAritize( mMSwitch( mMDebugInfo, mMMetaTrait( Detect, __VA_ARGS__ ) ), (C, __VA_ARGS__) )
#define mMDebugInfoRep( C, ... ) mMXP##C( mMDebugInfo_ )mMXP##C((mMIInc(C),__VA_ARGS__)) //(mMExpDo(mMGlue( mM, C)##DebugInfo_(mMIInc(C),__VA_ARGS__))
#define mMDebugInfo1( C, ... ) mMAritize( mMSwitch( mMDebugInfo, mMMetaTrait( Detect, __VA_ARGS__ ) ), (mMIInc(C), __VA_ARGS__) )
#define mMDebugInfo_Case_Nil(...) [Nil]
#define mMDebugInfo_Case_CntArgs(C,I,...)
mMDebugInfoRep(C,I),mMDebugInfoRep(C,__VA_ARGS__)
#define mMDebugInfo_Case_PrnNull(C,I) [()]
#define mMDebugInfo_Case_Prn(C,I) ( mMDebugInfoRep(C,mMDPrn(I)) )
#define mMDebugInfo_Case_ActFn(C,I) mMAritize( mMDebugInfo_Case_Fn, (C, I, mMTrait_Fn_mM##I) )
#define mMDebugInfo_Case_PassFn(C,I) mMAritize( mMDebugInfo_Case_Fn, (C, mMTrait_Fn_mM##I) )
#define mMDebugInfo_Case_Fn( C,Name, Reg, ArgCnt, PArgs ) [Name:ArgCnt]( mMAritize( mMSwitch( mMDebugInfo_Case_Fn, ArgCnt ), (C, mMDPrn( PArgs ) )) )
#define mMDebugInfo_Case_Fn_Case_V(C, _1, ...) mMDebugInfoRep(C, _1), mMDebugInfoRep(C, __VA_ARGS__)
#define mMDebugInfo_Case_Fn_Case_0(...) [Nil]
#define mMDebugInfo_Case_Fn_Case_1(C, _1, ...) mMDebugInfoRep(C, _1)
#define mMDebugInfo_Case_Fn_Case_2(C, _1, _2, ...) mMDebugInfoRep(C, _1), mMDebugInfoRep(C, _2)
#define mMDebugInfo_Case_Fn_Case_3(C, _1, _2, _3, ...) mMDebugInfoRep(C, _1), mMDebugInfoRep(C, _2), mMDebugInfoRep(C, _3)
#define mMDebugInfo_Case_Fn_Case_4(C, _1, _2, _3, _4, ...) mMDebugInfoRep(C, _1), mMDebugInfoRep(C, _2), mMDebugInfoRep(C, _3), mMDebugInfoRep(C, _4)
#define mMDebugInfo_Case_Int(C,I) [Num:I]
#define mMDebugInfo_Case_Digit(C,I) [Dig:I]
#define mMDebugInfo_Case_Bool(C,I) [Bin:I]
#define mMDebugInfo_Case_CCode(C,I) [CCd:I]
#define mMDebugInfo_Case_UToken(C,I) [UT:I]
这是在递归解析嵌套表达式时没有问题的调试代码,例如:
this is debug code that has no problems recursively parsing nested expressions like:
DebugInfo( BInt( BNot( IAdd(4,BNot(IAdd(6,7)) ) ) ) );
"
产生:
"[BInt:1]( [BNot:1]( [IAdd:2]( [Dig:4], [BNot:1]( [IAdd:2]( [Dig:6], [Dig:7] ) ) ) ) )"
示例表达式中的宏函数处于非活动形式.当我激活表单时,问题就出现了 - 各个参数的解析链可能会变得任意长,并且在使用之前它们没有得到完全解决.
The macro functions in the example expression are in inactive form. The problem is happening when I activate the form - the parse chain for the individual arguments can get arbitrarily long and they aren't getting resolved completely before they are getting used.
推荐答案
这是通常的成语:
#define mSwitch(Root, Case) mSwitch_(Root, Case)
#define mSwitch_(Root, Case) Root##_Case_##Case
C 预处理器宏的所有参数都在宏本身展开之前完全展开,除非 #
或 ##
运算符应用于他们;然后他们没有扩大.因此,要在 ##
之前获得完全扩展,您可以通过不使用 ##
的包装宏传递参数.
All of the arguments to a C preprocessor macro are fully expanded before the macro itself is expanded, unless the #
or ##
operator is applied to them; then they're not expanded. So to get full expansion before ##
, you pass the arguments through a wrapper macro that doesn't use ##
.
这篇关于如何保证粘贴前参数的完整宏扩展?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何保证粘贴前参数的完整宏扩展?
基础教程推荐
- Windows Media Foundation 录制音频 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 从 std::cin 读取密码 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01