C宏中的参数名是否会对以前的定义产生副作用?

C宏中的参数名是否会对以前的定义产生副作用?,c,macros,C,Macros,我知道在C宏中使用参数的情况,但在使用已定义的宏时会发生这种情况。但是,在定义它时,是否需要特别注意选择参数名称?预处理器是否以“原子”方式解析宏,以便不展开参数名 我的意思是,想象一下这个场景: #define MYVAL {is this safe?} #define ADDVALUES(MYVAL,YOURVAL) do{(MYVAL)+(YOURVAL);}while(0) int val=ADDVALUES(1,3); ADDVALUES宏如何解析?在定义ADDVALUES宏之前,

我知道在C宏中使用参数的情况,但在使用已定义的宏时会发生这种情况。但是,在定义它时,是否需要特别注意选择参数名称?预处理器是否以“原子”方式解析宏,以便不展开参数名

我的意思是,想象一下这个场景:

#define MYVAL {is this safe?}
#define ADDVALUES(MYVAL,YOURVAL) do{(MYVAL)+(YOURVAL);}while(0)

int val=ADDVALUES(1,3);
ADDVALUES宏如何解析?在定义ADDVALUES宏之前,MYVAL是否已展开

我没有读过关于在宏中选择参数名称的任何警告,因此我倾向于认为在解析宏之前不会展开它们的名称(我读过关于在宏中命名局部变量的警告、关于宏名称本身的警告、关于吞下分号的警告等,但没有读到关于选择参数名称的警告).

我尝试使用gcc 4.8.5

#define NV1 a
#define V1(NV1) b NV1
V1(foo)

gcc -E test.h
结果

b foo

因此,参数名称不会扩展为宏,并覆盖早期的冲突定义。参数
MYVAL
的范围与宏
MAYVAL
等对象的范围不同。引用本标准的相关部分:

参数由标识符的可选列表指定, 其范围从标识符列表中的声明扩展 直到终止#define预处理的新行字符 指令

示例中的最后一行将展开为

int val=do{(1)+(3);}while(0);

Ugh-除非我们有本地语言律师在场,否则可能必须扫描Clang的源代码才能得到答案。如果我将您的代码减去do while(0)部分,并将其放入编译器中,则不会出现错误-顶部宏未展开或使用。看来这至少是你想要的答案的一部分。现在是两次确认。非常感谢!我觉得很奇怪,很多地方都没有把这当作常见问题。非常感谢您的澄清。