I was investigating a compile and link issue within my program when I came across the following macro that was defined in a header and source file:
/* 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
Nothing out of the ordinary yet, until I saw the following information in the GCC output map file:
/* My Map File */
...
.rodata 0x08015694 _NVSize
...
My understanding of the map file is that if you see a symbol in the .rodata section of the map file, this symbol is being treated as a global variable by the compiler. But, this shouldn’t be the case because macros should be handled by the preprocessor before the compiler even parses the file. This macro should be replaced with it’s defined value before compiling.
Is this the standard way that GCC handles macros or is there some implementation specific reason that GCC would treat this as a global (debug setting maybe)? Also, what does this mean if my macro gets redefined in a different source file? Did I just redefine it for a single source file or did I modify a global variable, thereby changing _NVSize everywhere it’s used within my program?
I think the compiler is free to assign your macro to a global variable as long as it ensures that this produces the exact same result as if it did a textual replacement.
During the compilation the compiler can mark this global specially to denote that it is a macro constant value, so no re-assignment is possible, no address can be taken, etc.
If you redefine the macro in your sorce, the compiler might not perform this transformation (and treat it as you’d expect: a pre-compier textual replacement), perform it on one of the different values (or on all of them say, using different names for each occurrance), or do domething else 🙂