例如,我定义 AA 三次,是否合法?:
#include<stdio.h>
#define AA 10
#define AA 20
#define AA 30
int main() {
printf("AA");
}
答案 0 :(得分:9)
这在C和C ++中都不合法。
C标准草案N1570引用:
6.10.3宏替换
约束
1当两个替换列表相同时,替换列表是相同的 相同的数字,排序,拼写和空白分离,所有的空白区域 分离被认为是相同的。
2当前定义为类似对象宏的标识符不得由另一个宏重新定义
#define
预处理指令,除非第二个定义是类似对象的宏 定义和两个替换列表是相同的。同样,目前也是一个标识符 定义为类似函数的宏不应由另一个#define
重新定义 预处理指令,除非第二个定义是类似函数的宏定义 具有相同数量和参数的拼写,并且两个替换列表是 相同。
C ++标准草案N4582引用:
16.3宏替换[cpp.replace]
1当且仅当两者中的预处理令牌具有相同的数字时,两个替换列表是相同的, 排序,拼写和空白分离,其中所有空白分隔都被认为是相同的。
2当前定义为类似对象宏的标识符可能会被另一个
#define
预处理重新定义 指令规定第二个定义是一个类似对象的宏定义和两个替换列表 是相同的,否则该程序是不正确的。同样,一个标识符目前被定义为类似函数 宏可以由另一个#define
预处理指令重新定义,前提是第二个定义是a 类似于函数的宏定义,具有相同数量和参数的拼写,以及两个替换 列表是相同的,否则程序是不正确的。
答案 1 :(得分:6)
不,不是。 C标准明确规定它是违反约束的,6.10.3第2页:
当前定义为类似对象的宏的标识符不应该是 被另一个人重新定义
#define
预处理指令,除非第二个定义是类似于对象的宏定义,而两个替换列表是 相同。
因此,对于所有约束违规,您的编译器只需发出“诊断”即解释性消息。它可能会也可能不会继续编译您的代码。
要更直接地说明,你的代码是错误的,你的编译器必须告诉你。
答案 2 :(得分:5)
显然不推荐甚至认为它可以编译。
在您的示例中,您只需使用#define AA 30
一次。在其他情况下,如果要在尚未定义宏时定义宏,可以使用条件:
#ifndef AA
#define AA 30
#endif
另外,我认为您的意思是printf("%d\n", AA);
来打印宏,因为printf("AA");
只打印字符串文字AA
。
答案 3 :(得分:3)
让我们首先将printf更正为有用的东西:printf("%d", AA);
使用gcc
进行编译将产生两个警告“AA”被重新定义。警告非常重要,应该在C中避免,但结果将如预期的那样(30)。