如何保证在粘贴之前完全宏扩展参数? [英] How can I guarantee full macro expansion of a parameter before paste?

查看:133
本文介绍了如何保证在粘贴之前完全宏扩展参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个一般的宏:

  #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>或 ## 运算符应用于它们,那么它们不会扩展,因此在 ## ,您通过不使用 ## 的包装宏传递参数。


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆