我有一个像解决GCC转储定义
#define ONE 1
#define TWO 2
#define SUM (ONE+TWO)
如何倾倒SUM为“3”,解析值代码,在GCC 4.3或更高版本?
gcc -dM -E foo.h
似乎只是倾倒它。我如何获得它在编译阶段插入的实际值?
我有一个像解决GCC转储定义
#define ONE 1
#define TWO 2
#define SUM (ONE+TWO)
如何倾倒SUM为“3”,解析值代码,在GCC 4.3或更高版本?
gcc -dM -E foo.h
似乎只是倾倒它。我如何获得它在编译阶段插入的实际值?
你不能。就编译器而言,预处理前的行printf("%d\n", SUM)
与行printf("%d\n", 1+2)
无法区分。编译器恰好执行称为constant folding的优化,即使在默认的优化级别(-O0
)中,也会在运行时将结果转换为常量3。
看到这些优化的输出并不是一个好方法。您可以使用-S
选项来查看生成的汇编代码并查看看起来像什么,但是如果您的程序比玩具大,那将是很多手动操作。您也可以使用-fdump-tree
选项之一查看分析树(请参阅GCC手册页)。
我已经理解了......这首先是一个糟糕的问题。我想我必须走另一条路。感谢提供不断折叠的提示,这非常有用。 – gccnewbie
你不能“甩” 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;
}
有了这个例子中有没有办法,你能证明SUM
是3
。
与其他答案相反,这个问题绝对有解决方案,尤其是对于gcc扩展。解析gcc -dM
的输出并生成一个包含__typeof__(MACRO) foo = MACRO;
形式的行的C文件,并从那里开始。如果没有__typeof__
,只需使用long double
即可处理所有算术类型。
查看编译器生成的汇编代码。 –
但是'SUM'不是3,它是'ONE + TWO'。宏在他们出现的地方展开,这就是他们的工作方式。在'SUM'的定义之后尝试通过定义'ONE',将其重新定义为不同的东西,然后将SUM插入到源中。 –