问题描述
我知道在C宏中使用参数时的argument prescan,但是当您使用已经定义的宏时就会发生这种情况。但是,当您定义时,在选择参数名称时是否需要特别注意?预处理程序是否以“原子”方式解析宏,以便不扩展参数名称?
我的意思是,想象一下这种情况:
#define MYVAL {is this safe?}
#define ADDVALUES(MYVAL,YOURVAL) do{(MYVAL)+(YOURVAL);}while(0)
int val=ADDVALUES(1,3);
如何解析 ADDVALUES宏?在定义ADDVALUES宏之前,MYVAL是否已扩展?
我还没有阅读任何有关在宏中选择参数名称的警告,因此我倾向于认为在解析宏之前它们的名称不会扩展(我已经阅读了有关在宏中命名局部变量的警告,关于宏名称本身的警告,关于吞下分号等,但与选择参数名称无关。
解决方法
参数MYVAL
的范围不同于类对象宏MAYVAL
的范围。引用标准的相关部分6.10.3,p10:
参数由可选的标识符列表指定, 其范围从标识符列表中的声明扩展 直到换行符终止#define预处理为止 指令。
给定示例中的最后一行将扩展为
int val=do{(1)+(3);}while(0);
,
我尝试使用gcc 4.8.5
#define NV1 a
#define V1(NV1) b NV1
V1(foo)
gcc -E test.h
结果
b foo
因此,参数名称不会扩展为宏,并且会覆盖先前冲突的定义