该标准未使用此行指定参数的评估顺序:
参数的评估顺序未指定。
做什么
在没有表达式求值顺序限制的情况下可以生成更好的代码
意味着?
例如,要求所有编译器从左到右评估函数参数有什么缺点?由于这个未指定的规范,编译器会执行哪些类型的优化?
该标准未使用此行指定参数的评估顺序:
参数的评估顺序未指定。
做什么
在没有表达式求值顺序限制的情况下可以生成更好的代码
意味着?
例如,要求所有编译器从左到右评估函数参数有什么缺点?由于这个未指定的规范,编译器会执行哪些类型的优化?
允许编译器重新排序操作数的评估增加了更多的优化空间。
这是一个完全虚构的示例,用于说明目的。
假设处理器可以:
现在假设你有一个函数调用如下:
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 个周期。
这又是完全人为的。现代处理器比这复杂得多。但你明白了。
这是一个简单的例子。假设你有一个函数调用如下:
// 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”。这被称为公共子表达式消除。