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