2011-09-27 72 views
1

我有一个像解决GCC转储定义

#define ONE 1 
#define TWO 2 
#define SUM (ONE+TWO) 

如何倾倒SUM为“3”,解析值代码,在GCC 4.3或更高版本?

gcc -dM -E foo.h似乎只是倾倒它。我如何获得它在编译阶段插入的实际值?

+1

查看编译器生成的汇编代码。 –

+3

但是'SUM'不是3,它是'ONE + TWO'。宏在他们出现的地方展开,这就是他们的工作方式。在'SUM'的定义之后尝试通过定义'ONE',将其重新定义为不同的东西,然后将SUM插入到源中。 –

回答

2

你不能。就编译器而言,预处理前的行printf("%d\n", SUM)与行printf("%d\n", 1+2)无法区分。编译器恰好执行称为constant folding的优化,即使在默认的优化级别(-O0)中,也会在运行时将结果转换为常量3。

看到这些优化的输出并不是一个好方法。您可以使用-S选项来查看生成的汇编代码并查看看起来像什么,但是如果您的程序比玩具大,那将是很多手动操作。您也可以使用-fdump-tree选项之一查看分析树(请参阅GCC手册页)。

+0

我已经理解了......这首先是一个糟糕的问题。我想我必须走另一条路。感谢提供不断折叠的提示,这非常有用。 – gccnewbie

0

一种方法是停在预编译器阶段(-E)并检查该输出。

+1

这就是他已经做的 – Mat

+0

Doh!我错过了! :) –

1

你不能“甩” SUM为3,因为SUM不是3任何意义,它只是一个三个令牌ONE+TWO的序列。它变成什么取决于它扩展的上下文。

宏在源代码中出现的地方展开,宏代替只是在此之前的代币串。

你可以这样测试。

#include <stdio.h> 

#define ONE 1 
#define TWO 2 
#define SUM ONE+TWO 
int a = SUM; 
#undef ONE 
#define ONE 2 
int b = SUM; 

int main() 
{ 
    printf("a = %d\nb = %d\n", a, b); 
    return 0; 
} 

再举一例:

#include <stdio.h> 
#define ONE 1 
#define TWO 2 
#define SUM ONE+TWO 
int main() 
{ 
    /* prints 6, not 2 */ 
    printf("5 - SUM = %d\n", 5 - SUM); 
    return 0; 
} 

有了这个例子中有没有办法,你能证明SUM3

+0

好吧,我的代码有错误,如果我把它写成'#define SUM(ONE + TWO)',会怎么样?它仍然打印未触摸,但最后一个例子会显示2.任何方式将其转储为3? – gccnewbie

+0

我想我应该坚持像printf这样的“输出”方法,或者为转储写外部分析器。是的,我的问题最初是坏的。 – gccnewbie

1

与其他答案相反,这个问题绝对有解决方案,尤其是对于gcc扩展。解析gcc -dM的输出并生成一个包含__typeof__(MACRO) foo = MACRO;形式的行的C文件,并从那里开始。如果没有__typeof__,只需使用long double即可处理所有算术类型。