如何访问由宏定义隐藏的全局变量?

是否可以访问已在(自引用)宏中使用的全局范围的变量? 我正在使用用于指代此类宏的术语。
请参阅gcc.gnu.org/onlinedocs/cpp/Self-Referential-Macros.html
我的示例代码基于那里显示的示例代码。

简单示例:

#include  int foo = 10; /*A variable at global scope. There may be a few of these.*/ #define foo (4 + foo) /*A self-referential macro. There may be a few of these.*/ int main() { printf("foo = %d\n", foo); /*Prints 14. The value after the macro expansion */ /*Is there any way to access the global variable *foo* here?*/ return 0; } 

是的,您可以使用#undef foo删除宏定义。

是否可以访问已在自引用宏中使用的全局范围的变量?

不它不是。 FWIW,将全局变量重新定义为自引用宏是非常丑陋和糟糕的品味,并使代码难以理解。 不要那样做。

阅读有关C中各种转换阶段的更多信息(稍后,另请参阅C11标准n1570 )。 在实际解析之前(概念上)进行预处理 。

在实践中,不要#define foo ,但是例如#define FOO_MAC并适当地使用FOO_MACfoo (正如Eric Postpischil所回答的,你可能会使用#undef ,但这会使代码的可读性降低)。

顺便说一句,你可以得到预处理的表格(作为文本文件)。 使用GCC ,将其调用为

 gcc -Wall -C -E yourfoocode.c > yourfoocode.i 

然后在文件yourfoocode.i查找寻呼机或编辑器

另请阅读cpp的文档 。

特别是在GCC中,您还可以在全局变量声明中使用asm标签 (例如int otherfoo asm ("foo"); )来声明位于同一位置的另一个变量。 但这会让读者感到困惑并且可能会扰乱编译器优化传递(例如&foo != &otherfoo可能会优化为true但是为false),因此您不希望这样做。

请注意,C编程需要很多良好的约定和样​​式才能具有可读代码,因此在实践中您应该永远不会发生这种情况。 如果是这样,您需要重写代码(仅出于可读性原因)。

代码是可读性和可维护性的负担。
我希望你只是问这个,因为它是你需要应付的一些遗留代码,我觉得你。

你最接近访问全局变量,对显示的代码的更改最少,而不是添加另一个代码文件,我想是

 #include  int foo = 10; /*A variable at global scope. There may be a few of these.*/ int* backdoorfoo = &foo; #define foo (4 + foo) /*A self-referential macro. There may be a few of these.*/ int main() { printf("foo = %d\n", foo); /*Prints 14. The value after the macro expansion */ printf("foo = %d\n", *backdoorfoo); /*Prints 10, via dereferencing the differently named pointer. */ return 0; } 

请注意,使用#undef也是一种可能的解决方案,但在我看来,这只会让事情变得比现在更糟糕。

另一种方法是,如果你不能改变可怕的代码但是允许添加代码文件,那就是利用你的foo是全局的这一事实。
它允许从第二个代码文件访问实际的全局变量,该文件不包含宏障碍。

main.c中:

 #include  int foo = 10; /*A variable at global scope. There may be a few of these.*/ #define foo (4 + foo) /*A self-referential macro. There may be a few of these.*/ void printfoo(void); /* only needed for demo */ int main() { printf("foo = %d\n", foo); /*Prints 14. The value after the macro expansion */ printfoo(); /* Only needed for demo. Prints 10, the value of global foo variable. */ return 0; } 

second.c:

 #include  extern int foo; void printfoo(void) { printf("foo = %d\n", foo); /*Prints 14. The value after the macro expansion */ }