一个关于C语言宏替换的问题 在之前的一个项目中,通过macro来定义了一组位掩码: #define FLAG_TYPE1 0x0001 #define FLAG_TYPE2 0x0002 #define FLAG_TYPE3 0x0004 #define FLAG_TYPE4 0x0008 ... #define TYPE(type) (FLAG_TYPE##type) (这里对实例进行了简化,实例中将 TPYE 定义为 1<<(type-1) 并不妥当。)
由于使用这组位掩码的地方并不止一处,使用这个macro时传递的type参数并不是单纯的1、2、3、4,而是有着使用者自己的逻辑。 比如某使用者有如下定义: #define COLOR_RED 1 #define COLOR_GREEN 2 #define COLOR_BLUE 3 如果写作 TYPE(1) 很不具可读性,写作 TYPE(COLOR_RED) 就好多了。 但是这时候发现,TYPE(COLOR_RED)在完成宏替换后变成了FLAG_TYPECOLOR_RED,并不是希望的FLAG_TYPE1。 怎么办呢?支持TYPE(COLOR_RED) => FLAG_TYPE1的宏替换能实现吗? 其实只要将TYPE这个宏换个写法就好了: #define _TYPE(type) (FLAG_TYPE##type) #define TYPE(type) _TYPE(type) 这样,TYPE(COLOR_RED)就能替换成FLAG_TYPE1。替换过程如下: TYPE(COLOR_RED) => _TYPE(COLOR_RED) => _TYPE(1) => FLAG_TYPE1 为什么会这样呢?摘抄一段C标准: After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. 宏替换是从左到右被扫描,匹配到 ( 后,TYPE被展开,得到_TYPE; _TYPE的参数COLOR_RED接着被展开了,因为COLOR_RED没有与 # 或 ## 相连接。而最开始的那种写法之所以不对,就是因为这一步COLOR_RED与 ## 相连,token被拼装了; 之后_TYPE再被展开,最终得到期待的FLAG_TYPE1。
|