【问题标题】:Can the parameter names in a C macro have side effects from previous definitions?C 宏中的参数名称是否会对以前的定义产生副作用?
【发布时间】:2020-08-13 17:28:08
【问题描述】:

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

我的意思是,想象一下这种情况:

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

int val=ADDVALUES(1,3);

ADDVALUES 宏是如何解析的? MYVAL 是否在定义 ADDVALUES 宏之前展开?

我没有读过任何关于在宏中选择参数名称的警告,所以我倾向于相信在宏被解析之前它们的名字没有被扩展(我已经读过关于在宏中命名局部变量的警告,关于宏名本身,关于吞下分号等,但没有关于选择参数名称)。

【问题讨论】:

  • 呃 - 除非我们手边有当地语言律师,否则可能必须扫描 Clang 的源代码才能得到答案。
  • 如果我将您的代码减去 do while(0) 部分,然后将其放入编译器中,则不会出现错误 - 顶部宏未展开或使用。似乎这至少是您想要的答案的一部分。 onlinegdb.com/H1ws9g7GP

标签: c macros


【解决方案1】:

参数MYVAL 的范围与类对象宏MAYVAL 的范围不同。引用标准的相关部分,6.10.3,p10

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

给定示例中的最后一行将扩展为

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

【讨论】:

  • 非常感谢!我发现在很多地方没有将其作为常见问题解答很奇怪。非常感谢您的澄清。
【解决方案2】:

我尝试使用 gcc 4.8.5

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

gcc -E test.h

结果

b foo

因此参数名称不会扩展为宏并覆盖之前的冲突定义

【讨论】:

  • 现在是 2 次确认。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-18
相关资源
最近更新 更多