编译器优化,划分宏扩展

时间:2013-08-01 11:35:20

标签: c compiler-construction

我有以下代码,

情景1

/* get count of elements in an array */
#define COUNT(x)         sizeof(x)/sizeof(x[0])

struct Data data[] = {/* some data goes here */};

int count = COUNT(data);

情景2

#define TOTAL            32
#define EACH              4
int count = (TOTAL/EACH)

我知道宏在预处理期间被解析,而sizeof是一个编译时运算符,但是除法如何:在编译期间它是否得到优化?

是否有任何工具可以看到编译器完成的优化?

1 个答案:

答案 0 :(得分:4)

通常您可以让编译器显示生成的汇编代码。使用Visual C ++,您可以使用/Fa<file>选项执行此操作。 gcc具有-S选项。

至于你的问题:大多数编译器应该预先计算常量表达式,至少在高于O0的优化级别。

让我们看一下您的示例场景:

#define COUNT(x)         sizeof(x)/sizeof(x[0])
int data[] = {1, 2, 3, 4, 5};
int count = COUNT(data);

使用cl /c /Fascenario1.asm scenario1.c编译产生:

...
PUBLIC  _data
PUBLIC  _count
_DATA   SEGMENT
_data   DD  01H
    DD  02H
    DD  03H
    DD  04H
    DD  05H
_count  DD  05H
_DATA   ENDS
END

你看到count的值接近结尾,而且确实是5.所以即使没有打开优化,编译器也会计算出这个值。

你的第二个场景:

#define TOTAL            32
#define EACH              4
int count = (TOTAL/EACH);

产量

...
PUBLIC  _count
_DATA   SEGMENT
_count  DD  08H
_DATA   ENDS
END

表达式也是预先计算的。

在更高的优化级别上,编译器在传递编译时常量时甚至可以评估更复杂的表达式,这种情况并不少见。作为一个例子,我曾经看过交换两个整数的三种不同方式的代码,一旦我对编译器进行了优化,只需完全抛出对swap方法的调用,用我的test printf替换参数。已交换的价值。