При каких обстоятельствах компилятор может изменить порядок выполнения операторов программы? - PullRequest
2 голосов
/ 15 мая 2009

Если это не настоящий вопрос , тогда не стесняйтесь закрывать;)

Ответы [ 3 ]

9 голосов
/ 15 мая 2009

Не только компилятор может изменить порядок выполнения (в основном для оптимизации), большинство современных процессоров тоже делают это. Узнайте больше о переупорядочении выполнения и барьерах памяти .

5 голосов
/ 15 мая 2009

Компилятор может изменить порядок выполнения операторов, когда он считает это целесообразным для целей оптимизации, и когда такие изменения не изменят наблюдаемое поведение кода.

Очень простой пример -

int func (int value)
{
    int result = value*2;
    if (value > 10)
    {
       return result;
    }
    else
    {
       return 0;
    }
}

Наивный компилятор может сгенерировать для этого код в точности в указанной последовательности. Сначала вычислите «результат» и верните его только в том случае, если исходное значение больше 10 (если это не так, «результат» будет проигнорирован - вычисляется без необходимости).

Однако здравомыслящий компилятор увидит, что вычисление «результата» необходимо только тогда, когда «значение» больше 10, поэтому может легко переместить вычисление «значение * 2» в первые фигурные скобки и делать это только в том случае, «value» на самом деле больше 10 (не говоря уже о том, что компилятор не действительно смотрит на код C при оптимизации - он работает на более низких уровнях).

Это всего лишь простой пример. Гораздо более сложные примеры могут быть созданы. Вполне возможно, что функция C в конечном итоге будет выглядеть совсем не так, как ее представление C в скомпилированной форме, с достаточно агрессивной оптимизацией.

4 голосов
/ 15 мая 2009

Многие компиляторы используют то, что называется "устранение общих подвыражений". Например, если у вас был следующий код:

for(int i=0; i<100; i++) {
    x += y * i * 15;
}

компилятор заметил бы, что y * 15 является инвариантом (его значение не изменяется). Таким образом, он вычислит y * 15, поместит результат в регистр и изменит инструкцию цикла на "x + = r0 * i". Это своего рода надуманный пример, но вы часто видите подобные выражения при работе с индексами массива или любым другим типом ситуации + базовый + смещение.

...