当我遇到在头文件和源文件中定义的以下宏时,我正在研究程序中的编译和链接问题:
/* file_A.c */
#ifndef _NVSize
#define _NVSize 1
#endif
/* file_B.c */
#include "My_Header.h"
#ifndef _NVSize
#define _NVSize 1
#endif
/* My_Header.h */
#define _NVSize 1024
在我看到GCC输出映射文件中的以下信息之前,没有任何异常:
/* My Map File */
...
.rodata 0x08015694 _NVSize
...
我对地图文件的理解是,如果在地图文件的.rodata部分中看到符号,则编码器会将此符号视为全局变量。但是,情况并非如此,因为在编译器甚至解析文件之前,宏应该由预处理器处理。在编译之前,应该用它的定义值替换这个宏。
这是GCC处理宏的标准方式,还是有一些实现特定的原因,GCC会将其视为全局(可能是调试设置)?此外,如果我的宏在不同的源文件中重新定义,这意味着什么?我是仅仅为单个源文件重新定义它还是修改了一个全局变量,从而在我的程序中使用的所有地方都改变_NVSize?
答案 0 :(得分:3)
我认为编译器可以自由地将宏分配给全局变量,只要它确保产生完全相同的结果就像它进行文本替换一样。
在编译期间,编译器可以专门将此全局标记为表示它是宏常量值,因此不能重新赋值,不能使用地址等。
如果您在自己的内容中重新定义宏,编译器可能无法执行此转换(并按照您的预期处理它:预编译器文本替换),在其中一个不同的值上执行(或者所有人都说,为每个事件使用不同的名称),或做其他事情:)
答案 1 :(得分:1)
宏在预处理器步骤中被替换,编译器只看到替换结果。因此,如果它看到宏名称,那么我的赌注是宏没有在使用点定义。它在特定#define _NVSize
和#undef _NVSize
之间定义。不首先使用#undef
重新定义现有宏应该会导致预处理程序错误AFAIR。