12

该标准未使用此行指定参数的评估顺序:

参数的评估顺序未指定。

做什么

在没有表达式求值顺序限制的情况下可以生成更好的代码

意味着?

例如,要求所有编译器从左到右评估函数参数有什么缺点?由于这个未指定的规范,编译器会执行哪些类型的优化?

4

2 回答 2

29

允许编译器重新排序操作数的评估增加了更多的优化空间。

这是一个完全虚构的示例,用于说明目的。

假设处理器可以:

  • 每个周期发出 1 条指令。
  • 在 1 个周期内执行加法。
  • 在 3 个周期内执行一次乘法。
  • 可以同时执行加法和乘法。

现在假设你有一个函数调用如下:

foo(a += 1, b += 2, c += 3, d *= 10);

如果您要在没有OOE的处理器上从左到右执行此操作:

Cycle - Operation
0     -    a += 1
1     -    b += 2
2     -    c += 3
3     -    d *= 10
4     -    d *= 10
5     -    d *= 10

现在,如果您允许编译器重新排序它们:(并首先开始乘法)

Cycle - Operation
0     -    d *= 10
1     -    a += 1, d *= 10
2     -    b += 2, d *= 10
3     -    c += 3

所以 6 个周期与 4 个周期。

这又是完全人为的。现代处理器比这复杂得多。但你明白了。

于 2012-09-22T03:36:20.177 回答
4

这是一个简单的例子。假设你有一个函数调用如下:

// assume that p is a pointer to an integer
foo(*p * 3, bar(), *p * 3 + 1);

编译器需要取消引用p两次(并根据结果进行一些计算)并调用bar一次。如果编译器很聪明,它可能会将评估重新排序为

int temp = *p * 3;
foo(temp, bar(), temp + 1);

这样,它只需执行一次“取消引用,乘以 3”。这被称为公共子表达式消除。

于 2012-09-24T15:03:33.897 回答