2017-04-10 72 views
1

捕获请看下面的代码:强制C预处理器的宏价值

#include <stdio.h> 

#define MACRO_A "early" 
#define MACRO_B MACRO_A 
#undef MACRO_A 
#define MACRO_A "late" 
#define MACRO_C MACRO_A 

int main(void) { 
     printf("MACRO_B = %s, MACRO_C = %s\n", MACRO_B, MACRO_C); 
     return 0; 
} 

我预计MACRO_B将捕获MACRO_A的价值在它被定义时,即“早”。但上面的代码打印:

MACRO_B = late, MACRO_C = late 

有没有办法迫使MACRO_B捕捉MACRO_A当时的价值就被定义? (注:在不确定性的情况下,假设我们使用gcc。)

真正使用的情况是,我使用的是单一的宏观形式来创建一个共享的定义不同的扩展:一个扩展定义struct布局,重新定义会为结构创建初始化程序等。这使我可以将所有信息保存在一个地方。

出于这个原因,它会捕捉到“当前”宏扩展在另一个宏,这样我可以重新使用原来的定义而不会失去它的状态是有用的。

+0

号宏替换发生,只有当前定义。否则它不会是C预处理器。 –

+0

是的,看起来这确实是http://stackoverflow.com/questions/34486726/c-preprocessor-evaluate-macro-early的重复,尽管关注整数,它在回答问题方面做得更好。很高兴删除这一个... –

回答

0

这种失败的使用宏的目的。宏不应该用于全局变量。

一种替代方法是使用全局变量。使用静态全局变量并将它们设置为宏的值,而不是创建宏。

像这样:

#include <stdio.h> 

#define MACRO_A "early" 
static char* a = MACRO_A; 
#define MACRO_B MACRO_A 
static char* b = MACRO_B; 
#undef MACRO_A 
#define MACRO_A "late" 
#define MACRO_C MACRO_A 
static char* c = MACRO_C; 

int main(void) { 
     printf("MACRO_B = %s, MACRO_C = %s\n", a, c); 
     return 0; 
} 
+0

那么,这正是我使用宏的方式。我只是希望我不必将我的.h文件(宏定义)与我的.c文件(宏扩展)混合,如果你明白我的意思。但是我可以重构代码以避免它。 –

0

作为C预处理仅由其他文本替换文本时,将发生以下情况时printf线将被处理:

  • MACRO_B将由文本替换如先前所定义的MACRO_A; "late"

以相同的方式::

  • 在递归方式,MACRO_A将由其当前定义替换

    • MACRO_C将由MACRO_A代替如前面所定义;
    • 然后以递归的方式,MACRO_A将被"late"取代。