#define很多次没有#undef,这是合法的吗?

pen*_* xu 1 c c-preprocessor

例如,我将AA定义三次,是否合法?:

#include<stdio.h>
#define AA 10
#define AA 20
#define AA 30
int main() {
    printf("AA");
}
Run Code Online (Sandbox Code Playgroud)

cpp*_*ner 9

这在C和C++中都不合法.

草案C标准N1570引用:

6.10.3宏替换

约束

1当且仅当两者中的预处理标记具有相同的数字,排序,拼写和空白分隔时,替换列表才相同,其中所有空白分隔都被认为是相同的.

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

草案C++标准N4582引用:

16.3宏替换[cpp.replace]

1当且仅当两者中的预处理标记具有相同的数字,排序,拼写和空白分隔时,两个替换列表是相同的,其中所有空白分隔都被认为是相同的.

2当前定义为类似对象的宏的标识符可以由另一个#define预处理指令重新定义,前提是第二个定义是类似于对象的宏定义,并且两个替换列表是相同的,否则程序是不正确的.同样地,当前定义为类似函数的宏的标识符可以由另一个#define预处理指令重新定义,条件是第二定义是具有相同数量和参数拼写的类似函数的宏定义,并且两个替换列表是相同的,否则该计划格式不正确.


Jen*_*edt 6

不它不是.C标准明确规定它是违反约束条款,6.10.3第2页:

#define除非第二个定义是类似于对象的宏定义且两个替换列表相同,否则当前定义为类似对象的宏的标识符不应由另一个预处理指令重新 定义.

因此,对于所有约束违规,您的编译器只需发出"诊断"即解释性消息.它可能会也可能不会继续编译您的代码.

要更直接地说明,您的代码是错误的,编译器必须告诉您.


flu*_*ter 5

显然不建议甚至认为它可以编译.在您的示例中,您只需使用#define AA 30一次.在其他情况下,如果要在尚未定义宏时定义宏,可以使用条件:

#ifndef AA
#define AA 30
#endif
Run Code Online (Sandbox Code Playgroud)

另外,我认为你的意思printf("%d\n", AA);是打印宏,因为printf("AA");只会打印字符串文字AA.