4

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

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

4

2 回答 2

3

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

编译时编译器可以专门标记这个全局变量,表示它是一个宏常量值,所以不能重新赋值,不能取地址等。

如果您在源代码中重新定义宏,编译器可能不会执行此转换(并按照您的预期对待它:预编译器文本替换),对不同的值之一执行它(或对所有这些值执行,为每个事件使用不同的名称),或者做其他事情:)

于 2012-04-15T12:18:51.390 回答
1

宏在预处理器步骤中被替换,编译器只看到替换的结果。因此,如果它看到宏名称,那么我敢打赌,宏没有在使用时定义。#define _NVSize它在特定和一个之间定义#undef _NVSize。在不使用第一个宏的情况下重新定义现有宏#undef应该会导致预处理器错误,AFAIR。

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

于 2012-04-15T13:02:57.777 回答