打印宏的名称和值

时间:2009-07-22 11:32:53

标签: c c-preprocessor

我有一个C程序,可以使用#define启用或禁用许多优化。当我运行我的程序时,我想知道在编译时定义了哪些宏。

所以我试着编写一个宏函数来打印宏的实际值。像这样:

SHOW_DEFINE(X){\
  if( IS_DEFINED(X) )\
      printf("%s is defined and as the value %d\n", #X, (int)X);\
  else\
      printf("%s is not defined\n", #X);\
}

但是我不知道如何使它工作,我怀疑它是不可能的,有没有人知道如何做到这一点?

(请注意,即使未定义宏,也必须编译!)

11 个答案:

答案 0 :(得分:28)

只要您愿意忍受SOMESTRING = SOMESTRING表明尚未定义SOMESTRING(查看令牌尚未重新定义!?!)的事实,那么以下内容应该:

#include <stdio.h>

#define STR(x)   #x
#define SHOW_DEFINE(x) printf("%s=%s\n", #x, STR(x))

#define CHARLIE -6
#define FRED 1
#define HARRY FRED
#define NORBERT ON_HOLIDAY
#define WALLY

int main()
{
    SHOW_DEFINE(BERT);
    SHOW_DEFINE(CHARLIE);
    SHOW_DEFINE(FRED);
    SHOW_DEFINE(HARRY);
    SHOW_DEFINE(NORBERT);
    SHOW_DEFINE(WALLY);

return 0;
}

输出结果为:

BERT=BERT
CHARLIE=-6
FRED=1
HARRY=1
NORBERT=ON_HOLIDAY
WALLY=

答案 1 :(得分:4)

编写扩展到另一个MACRO的MACRO需要预处理器在其上运行两次 那是没有做到的。

你可以写一个简单的文件,

// File check-defines.c
int printCompileTimeDefines()
{
#ifdef DEF1
  printf ("defined : DEF1\n");
#else // DEF1
  printf ("undefined: DEF1\n");
#endif // DEF1
// and so on...
}

对此文件使用与其他文件相同的编译时定义行。
在开始的某个时候调用该函数。

如果源文件中有#DEFINE行,而不是Makefile,则 将它们移动到另一个Header文件,并在所有源文件中包含该标题,
包括这个check-defines.c

希望您在所有源文件中都拥有相同的定义集 否则,重新检查定义的策略是明智的。


自动生成此功能
您可以使用M4宏语言(实际上甚至是AWK script M4 成为您的预处理器。

答案 2 :(得分:2)

#ifdef MYMACRO
  printf("MYMACRO defined: %d\r\n", MYMACRO);
#endif

我不认为你想做的事情是可能的。您在运行时询问已在编译之前处理的信息。字符串“MYMACRO”在CPP将其扩展到程序内的值后意味着什么。

答案 3 :(得分:2)

您没有指定您使用的编译器。如果这是gcc,gcc -E可能会帮助您,因为它在预处理阶段后停止,并打印预处理结果。如果你用原始文件区分gcc -E结果,你可能会得到你想要的一部分。

答案 4 :(得分:2)

为什么不简单地使用预处理器进行测试?

 #if defined(X)
      printf("%s is defined and as the value %d\n", #X, (int)X);
 #else
      printf("%s is not defined\n", #X);
 #endif

还可以将其嵌入到另一个测试中,而不是每次都打印它:

 #if define(SHOW_DEFINE)
 #if defined(X)
      printf("%s is defined and as the value %d\n", #X, (int)X);
 #else
      printf("%s is not defined\n", #X);
 #endif
 #endif

答案 5 :(得分:1)

来自boost的

Wave library也可以帮助你做你想做的事情。如果你的项目足够大,我认为值得尝试。它是一个C ++预处理器,但它们在任何方面都是相同的:)

答案 6 :(得分:1)

我相信你想做的事情是不可能的。如果您能够改变#define的工作方式,那么我建议如下:

#define ON 1
#define OFF 2

#define OPTIMIZE_FOO ON
#define OPTIMIZE_BAR OFF

#define SHOW_DEFINE(val)\
    if(val == ON) printf(#val" is ON\n");\
    else printf(#val" is OFF\n");

答案 7 :(得分:1)

确实不可能,问题是“未定义”部分。如果您依靠宏值来激活/停用代码的某些部分,那么您可以这样做:

#define SHOW_DEFINE(X) \
do { \
if (X > 0) \
    printf("%s %d\n", #X, (int)X);   \
else \
    printf("%s not defined\n", #X);   \
} while(0)

答案 8 :(得分:1)

基于Chrisharris,回答我这样做了。 虽然我的答案不是很好,但这完全是我想要的。

#define STR(x)   #x
#define SHOW_DEFINE(x) printf("%s %s\n", #x, strcmp(STR(x),#x)!=0?"is defined":"is NOT    defined")

只有我发现的错误是定义不能是#define XXX XXX(XXX等于XXX)。

答案 9 :(得分:0)

这个问题与Macro which prints an expression and evaluates it (with __STRING)非常接近。 Chrisharris的答案与上一个问题的答案非常接近。

答案 10 :(得分:0)

您可以使用初始化为1的整数变量。 将#define乘以此变量并打印变量值。