2009-07-22 82 views
7

我有一个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);\ 
} 

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

(注意,没有定义的宏,即使这需要编译!)

回答

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成为您的预处理器。

+0

接受m4的回答。当您添加另一个预处理步骤时,这变得很容易。我做了SHOW_DEFINE(X,Y,Z ...),这更好。然而,它使sens,因为我需要m4的其他东西。 – Ben 2009-07-22 12:32:46

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

我不认为你正在尝试做的是可能的。您在运行时要求提供在编译之前已处理的信息。字符串“MYMACRO”在CPP将其扩展到您的程序中的值后没有任何意义。

+0

好吧,这是我想避免的,因为我有许多#ifdef #else #endif。 – Ben 2009-07-22 11:49:37

2

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

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 
+0

@philippe,那么,这就是我和kjfletch似乎建议的。但他希望避免写下所有这些,这就是为什么我建议使用M4或AWK脚本的原因。 – nik 2009-07-22 12:03:28

+0

这就是我现在所做的,该列表从不是最新的,它只需要一个特殊的文件就可以实现这个目的:( – Ben 2009-07-22 12:05:11

1

Wave library从boost可以帮助也做你想要什么。如果你的项目足够大,我认为这是值得尝试的。这是一个C++预处理器,但它们以任何方式:)

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"); 
1

这是不可能的确,这个问题是在“没有定义”的一部分。只要你愿意忍受的事实,SOMESTRING = SOMESTRING表示SOMESTRING

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

:如果您想对宏值依赖激活/关闭部分代码的,那么你可以简单地做尚未确定(!?!把它看作令牌还没有被重新定义),那么下面应该做的:

#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= 
0

基于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)。

0

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