c-我可以用另一个#define指令重新定义宏吗



我想用另一个值重新定义宏常量的值。现在我知道了使用#undef然后重新使用#define宏本身的技术,比如:

#define LEN_OSG 59
....
#undef LEN_OSG
#define LEN_OSG 70

我尝试缩写它,发现可以通过另一个#define指令来重新定义宏常量:

#define LEN_OSG 59
....
#define LEN_OSG 70

示例程序:

#include <stdio.h>
#define LEN_OSG 59
int main()
{
printf("LEN_OSG is %d.n",LEN_OSG);
#define LEN_OSG 70
printf("LEN_OSG is %d.",LEN_OSG);
}

当然,gcc和clang都给了我警告:

警告:"LEN_OSG"被重新定义。(gcc(

警告:'LEN_OSG'宏重新定义[-Wmacro重新定义](clang(

但他们确实编译了它(当然没有-Werror选项(,并给出了正确的结果:

Execution build compiler returned: 0
Program returned: 0
LEN_OSG is 59.
LEN_OSG is 70.

我的问题:

  • 是否可以忽略此特定警告,用另一个#define指令重新定义宏
  • 这是否涉及未定义的行为或对程序造成潜在危害

非常感谢。

重新定义宏(当重新定义不相同时(是违反约束。限制条件在C标准第6.10.3p2节中有详细说明:

当前定义为类对象宏的标识符应不能由另一个#define预处理指令重新定义,除非第二个定义是类似对象的宏定义两个替换列表是相同的同样当前定义为类似宏的函数的标识符不能由另一个#define预处理指令重新定义除非第二个定义是类似函数的宏具有相同数量和拼写的参数的定义,并且这两个替换列表是相同的。

第4p2节说明了以下关于约束冲突的内容:

如果出现在外部的"全部"或"全部不"要求如果违反了约束或运行时约束行为未定义未定义的行为以其他方式显示在本国际标准中行为"或通过省略任何明确的定义行为这三者在侧重点上没有区别;他们所有描述"未定义的行为"。

因此,重新定义宏会调用未定义的行为。如果要重新定义宏,则必须使用#undef

在重新定义宏之前,您应该真正习惯使用#undef!大多数编译器都会生成警告;然而,根据C99标准(以及C18标准——两者的段落相同(:

6.10.3宏替换

2当前定义为类对象宏的标识符不应被另一个#define预处理指令重新定义,除非第二个定义是类对象宏定义,并且两个替换列表相同。同样,当前定义为类函数宏的标识符不应被另一个#define预处理指令重新定义,除非第二个定义是具有相同参数数量和拼写的类函数宏定义,并且两个替换列表相同。

示例中LEN_OSG(类对象(宏的"替换列表"是59,然后是70,它们不完全相同。

最新更新