Как я могу гарантировать полное макрорасширение параметра перед вставкой?

У меня есть общий макрос:

#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?

Это хорошо работает если mSwitch передается литеральное значение, но если существует несколько слоев косвенности, или посреднические операции, mSwitch заканчивает тем, что вставил одного из тех, прежде чем они будут полностью расширены.

Я использую MSVC 2005.

Существует ли простой способ удостовериться, что параметр полностью расширен, прежде чем вставка сделана?

Спасибо


хорошо, не случается так что трудно дать пример, возможно:

  #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]

это - код отладки, который не имеет никаких проблем, рекурсивно анализирующих вложенные выражения как:

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] ) ) ) ) )"

Макро-функции в выражении в качестве примера находятся в неактивной форме. Проблема происходит, когда я активирую форму - цепочка синтаксического анализа для отдельных аргументов может стать произвольно длинной, и они не становятся разрешенными полностью, прежде чем они привыкнут.

7
задан Brian Tompsett - 汤莱恩 15 June 2016 в 21:53
поделиться

1 ответ

Это обычная идиома для этого:

#define mSwitch(Root, Case) mSwitch_(Root, Case)
#define mSwitch_(Root, Case) Root##_Case_##Case

Все аргументы макроса препроцессора C полностью раскрываются перед раскрытием самого макроса, если не К ним применяется оператор] # или ## ; тогда они не расширяются. Итак, чтобы получить полное раскрытие до ## , вы передаете аргументы через макрос оболочки, который не использует ## .

10
ответ дан 7 December 2019 в 01:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: