我想知道我的编译器针对“宏MACRO_NAME重新定义”抛出的警告的严重性。它在没有undef指令的头文件中重新定义,如下所示:
#define MACRO_NAME 3.14
/*other macro definition*/
#define MACRO_NAME 8192
在整个程序中,MACRO_NAME取什么值?它取决于编译器吗?这里是#undef必需的吗?
答案 0 :(得分:1)
如果编译,则用第二个宏的值覆盖第一个宏。
#include <stdio.h>
#define MACRO_NAME 3.14
/*other macro definition*/
#define MACRO_NAME 8192
int main()
{
printf("%d", MACRO_NAME);
return 0;
}
输出:8192
通常会收到此警告,并且应始终使用#undef
,因为根据C89标准,这样的重定义是无效的:
5:0:警告:“ MACRO_NAME”已重新定义
3:0:注意:这是先前定义的位置
由cpp.sh,onlinegdb.com和tutorialspoint.com验证。
答案 1 :(得分:1)
第二个宏int a;
#define VAL 100
a=VAL; // a is 100 here
#define VAL 200
a=VAL; // a is 200 here
被考虑在内。无论如何,这都是不好的做法,因为当新开发人员读取您编写的整个代码时,这可能会引起巨大的混乱。
通常,在不同的头文件中用不同的值定义的同一宏可能会发生,这时取决于这两个头文件的包含顺序。看到这种情况,这对您来说可能很容易,但是当新开发人员接管您的代码时,这会造成极大的混乱。
通常,将所有警告视为错误。然后,您不必担心宏将具有什么值。(摘自上面的评论)
我不建议您在没有undef的情况下重新定义宏
通常,您会收到此警告,并且应始终使用#undef,因为根据C89标准,这种重新定义无效:
一个很好的例子已经提出:
words
您可以看到问题所在:)
答案 2 :(得分:1)
来自C标准#6.10.3p2 [强调我的]
2当前定义为类对象宏的标识符不应由另一个#define预处理指令重新定义,除非第二个定义是类对象宏定义和两个替换列表完全相同。同样,当前定义为类函数宏的标识符不应由另一个#define预处理指令重新定义,除非第二个定义是具有相同编号和参数拼写且两个替换列表相同的类函数宏定义。
因此,根据标准,这无效,因为替换项(3.14
和8192
)不相同:
#define MACRO_NAME 3.14
/*other macro definition*/
#define MACRO_NAME 8192
您可以使用#undef
使此代码有效,如下所示:
#define MACRO_NAME 3.14
// the part of code using MACRO_NAME before #undef will expanded to 3.14
#undef MACRO_NAME
/*other macro definition*/
#define MACRO_NAME 8192
// after this the code using MACRO_NAME expanded to 8192
来自C标准#6.10.3.5p1(宏定义的范围) [已添加重点]
1 宏定义将持续(独立于块结构),直到遇到相应的#undef指令为止;或者(如果未遇到)直到预处理转换单元的末尾。宏定义没有任何意义。在翻译阶段4之后。
其他:
从C Standard#6.10.3.5p8开始,宏重新定义规则演示:
8示例6为了演示重新定义规则,以下顺序有效。
#define OBJ_LIKE (1-1) #define OBJ_LIKE /* white space */ (1-1) /* other */ #define FUNC_LIKE(a) ( a ) #define FUNC_LIKE( a )( /* note the white space */ \ a /* other stuff on this line */ )
但是以下重新定义无效:
#define OBJ_LIKE (0) // different token sequence #define OBJ_LIKE (1 - 1) // different white space #define FUNC_LIKE(b) ( a ) // different parameter usage #define FUNC_LIKE(b) ( b ) // different parameter spelling
答案 3 :(得分:1)
您正在做的事情无效:
C11标准规定:
6.10.3宏替换
约束
...
2当前定义为类对象宏的标识符不能由另一个#define
预处理指令重新定义,除非第二个定义是类对象宏定义和两个替换列表完全相同。当且仅当两个中的预处理令牌具有相同的数字,顺序,拼写和空格分隔(其中所有空格分隔均视为相同)时,两个替换列表相同。 / p>
对于
#define MACRO_NAME 3.14
#define MACRO_NAME 8192
替换列表不同。