如果是not a real question,请随时关闭;)
答案 0 :(得分:9)
不仅编译器可以重新排序执行(主要用于优化),大多数现代处理器也这样做。阅读有关执行重新排序和memory barriers的更多信息。
答案 1 :(得分:5)
当编译认为适合于优化目的时,编译器可以更改语句的执行顺序,并且当这些更改不会改变代码的可观察行为时。
一个非常简单的例子 -
int func (int value)
{
int result = value*2;
if (value > 10)
{
return result;
}
else
{
return 0;
}
}
一个天真的编译器可以按照所示的顺序为此生成代码。首先计算“结果”并仅在原始值大于10时返回(如果不是,则“结果”将被忽略 - 不必要地计算)。
但是,一个理智的编译器会发现只有当“value”大于10时才需要计算“result”,所以可以很容易地在第一个括号内移动计算“value * 2”,只有在“value”实际上大于10(不用说,编译器在优化时不会真正查看C代码 - 它在较低级别工作)。这只是一个简单的例子。可以创建更复杂的示例。很可能C函数最终看起来几乎没有像编译形式的C表示那样,具有足够的积极优化。
答案 2 :(得分:4)
许多编译器使用称为“公共子表达式消除”的东西。例如,如果您有以下代码:
for(int i=0; i<100; i++) {
x += y * i * 15;
}
编译器会注意到y * 15是不变的(其值不会改变)。因此它会计算y * 15,将结果粘贴到寄存器中并将循环语句更改为“x + = r0 * i”。这是一个人为的例子,但在使用数组索引或任何其他基本+偏移类型的情况时,你经常会看到这样的表达式。