如何保证在粘贴之前完全宏扩展参数? [英] 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 .do stuff
...更多特殊情况
如何保证变量在
mSwitch
?
之前, >如果
mSwitch
被传递一个文字值,但是如果有多层间接或中间操作,mSwitch会在它们完全展开之前粘贴其中一个。 我使用 MSVC 2005
。
感谢
有一个简单的方法可以确保一个参数在完成粘贴之前完全展开。
#
$ b 定义mMDebugInfo(...)mMDebugInfo(...)mMDebugExp(mMDebugInfo_(0,__VA_ARGS__))
#define mMDebugInfo_(C,...)mMAritize(mMSwitch(mMDebugInfo,mMMetaTrait(Detect,__VA_ARGS__)), ,__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__)), (C),__VA_ARGS__))
#define mMDebugInfo_Case_Nil(...)[Nil]
#define mMDebugInfo_Case_CntArgs(C,I,...)
(C,I)(mMDebugInfoRep(C,I),mMDebugInfoRep(C,__VA_ARGS__)
#define mMDebugInfo_Case_PrnNull(C,I)[()]
#define mMDebugInfo_Case_Prn (I))
#define mMDebugInfo_Case_PassFn(C,I)mMAritize(mMDebugInfo_Case_Fn,(C,I,mMTrait_Fn_mM ## I))
,I)mMAritize(mMDebugInfo_Case_Fn,(C,mMTrait_Fn_mM ## I))
#define mMDebugInfo_Case_Fn(C,Name,Reg,ArgCnt,PArgs)[Name:ArgCnt](mMAritize 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)
#定义mMDebugInfo_Case_Fn_Case_2(C,_1,_2,...)mMDebugInfoRep(C,_1),mMDebugInfoRep(C,_2)
#define mMDebugInfo_Case_Fn_Case_3(C,_1,_2,_3, (C,_1,_2,_3,_4,...)mMDebugInfoRep(C,_2),mMDebugInfoRep(C,_2),mMDebugInfoRep(C,_3),
_define mMDebugInfo_Case_Fn_Case_4 _1),mMDebugInfoRep(C,_2),mMDebugInfoRep(C,_3),mMDebugInfoRep(C,_4)
#define mMDebugInfo_Case_Int $ b #define mMDebugInfo_Case_Digit(C,I)
#define mMDebugInfo_Case_Bool(C,I)[Bin:I]
#define mMDebugInfo_Case_CCode I)[CCd:I]
#define mMDebugInfo_Case_UToken(C,I)[UT:I]
这是调试代码,没有问题递归解析嵌套表达式,如:
DebugInfo (IAdd(4,BNot(IAdd(6,7)))))));
这会产生:
[BInt:1]([BNot:1]([IAdd:2]([Dig:4],[BNot:1] :6],[Dig:7])))))
表达式处于非活动形式当我激活表单时发生问题 - 单个参数的解析链可以获得任意长度,并且在使用它们之前无法完全解决。
这是通常的习惯用法:
#define mSwitch(根,情况)mSwitch_(根,情况)
#define mSwitch_(根,情况)根###案例_ ##案例
除非#$ c $ ,所有C预处理器宏的参数都会在宏本身展开之前完全展开c>或
##
运算符应用于它们,那么它们不会扩展,因此在 ##
,您通过不使用 ##
的包装宏传递参数。
I have a general macro:
#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
how do I guarantee that the variable Case
is fully expanded before it gets pasted in 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.
I'm using MSVC 2005
.
Is there a simple way to make sure a parameter is fully expanded before pasting is done?
Thanks
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)) ) ) ) );
"
which yields:
"[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.
This is the usual idiom for this:
#define mSwitch(Root, Case) mSwitch_(Root, Case)
#define mSwitch_(Root, Case) Root##_Case_##Case
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 ##
.
这篇关于如何保证在粘贴之前完全宏扩展参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!