我对C预处理程序常量评估有一个基本问题,我想在理解这种情况下预处理程序是否有助于优化代码方面有所帮助。我了解到预处理器只是在代码中“替换文本”。通过该规则,即使常量表达式也可以在代码中替换。例如,以下代码:
#include <stdio.h>
#define MY_NUM 2+2*2
int main()
{
int a = 6/MY_NUM;
printf("a: %d\n", a);
return 0;
}
a
的值为7。这是因为预处理后的代码如下所示:
int main()
{
int a = 6/2+2*2;
printf("a: %d\n", a);
return 0;
}
我可以看到MY_NUM
在编译开始之前并未求值为6。当然,编译器随后会在编译时通过评估a
的值来优化代码。
我不确定预处理器常量折叠是否发生或是否可能。还是有任何方法(gcc中的标志)启用它。常规-O
优化不会启用此功能。无论如何,我们可以在这里更改预处理器的行为吗?
我的代码使用的是gcc 4.8.4。
答案 0 :(得分:2)
否,预处理器唯一评估任何表达式的时间是在#if
/ #elif
中。
您可以通过以令牌级联和大量宏的形式实现算术来伪造算术,但这比简单地做要困难得多
#define MY_NUM (2+2*2)
但是没有简单的编译器开关,因为宏扩展只是令牌替换。
答案 1 :(得分:0)
预处理器有其自己的常量计算器,它使用该计算器获取所有条件运算符#if #elif中表达式的值。
即使可以从预处理器令牌的替换列表中折叠常量,也绝不会这样做,只是因为它不知道是否预处理了C代码或某些其他文本/语言。
C预处理程序具有普遍用途,不仅限于C语言预处理。
C编译器可能在解析C令牌的解析器内部具有自己的常量折叠。