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:
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##
.