为什么我的#define宏似乎是全局的?

时间:2012-04-15 12:14:27

标签: c gcc

当我遇到在头文件和源文件中定义的以下宏时,我正在研究程序中的编译和链接问题:

/* 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?

2 个答案:

答案 0 :(得分:3)

我认为编译器可以自由地将宏分配给全局变量,只要它确保产生完全相同的结果就像它进行文本替换一样。

在编译期间,编译器可以专门将此全局标记为表示它是宏常量值,因此不能重新赋值,不能使用地址等。

如果您在自己的内容中重新定义宏,编译器可能无法执行此转换(并按照您的预期处理它:预编译器文本替换),在其中一个不同的值上执行(或者所有人都说,为每个事件使用不同的名称),或做其他事情:)

答案 1 :(得分:1)

宏在预处理器步骤中被替换,编译器只看到替换结果。因此,如果它看到宏名称,那么我的赌注是宏没有在使用点定义。它在特定#define _NVSize#undef _NVSize之间定义。不首先使用#undef重新定义现有宏应该会导致预处理程序错误AFAIR。

顺便说一句,你不应该用下划线开始你的宏名称。这些是为实现保留的。