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

时间:2016-05-02 06:53:23

标签: c c-preprocessor

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

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

4 个答案:

答案 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)。