2012-03-21 1 views
0

Я задал бы вопрос о компиляторах, в частности, о том, как они работают. Я бы поверила, что компиляторы всегда будут компилировать один и тот же машинный код для кода, который написан по-разному синтаксически, но делает то же самое. Это правда? Сочетает ли функционально подобный код с одним и тем же результатом независимо от синтаксических различий?Эффективный компилятор каждый раз компилируется в один и тот же результат?

, например:

int number = 2; 

бы компилировать то же самое, как:

int number; 
number = 2; 

или что

while True: 

будет такой же, как (я использую питона здесь в качестве примера):

while 1: 

Меня особенно интересуют компиляторы и интерпретаторы .net. компилятор JIT компилирует «во времени» одно и то же каждый раз? У интерпретаторов, таких как интерпретатор Python, «каждый раз интерпретируют» кодовый код?

спасибо!

+0

как два для петель одинаковы? –

+0

Что вы подразумеваете под «делает то же самое?» Последние две петли, которые вы на самом деле делаете, имеют разные вещи, поскольку, хотя они петли пять раз, значения i во время цикла различны. – templatetypedef

+1

Возможно, что 'for (int i = 0; i <5; i ++)' может быть скомпилировано с тем же объектным кодом, что и for (int i = 1; i <= 5; i ++) 'при определенных обстоятельствах, но в общий случай, который вы * не хотите, хотите, поскольку 'i' будет иметь другой диапазон значений. Если 'i' будет использоваться внутри цикла, это будет иметь значение. –

ответ

1
int number = 2; 

будет составлять одно и то же, как:

int number; number = 2; 

Вероятно, но не конечно. NB на многих языках декларация вообще не генерирует код.

или что

(int i = 0; i < 5; i++) 

будет такой же, как:

for (int i = 1; i <=5; i++) 

Конечно, нет! Разная семантика!

NB Это не соображение «эффективности».

компилятор JIT компилирует «во времени» к тому же самому себе каждый раз? У интерпретаторов, таких как интерпретатор Python, «интерпретируют» кодовый код точно так же каждый раз?

Теперь вы, кажется, задаете совершенно другой вопрос. Один и тот же исходный код всегда компилируется одинаково, по модулю JIT-эффектов и интерпретируется одинаково. Компьютеры детерминированы.

+0

Компьютеры могут быть детерминированными, но компиляторам вообще разрешено много свободы. Пока результирующая программа функционально корректна, в значительной степени любой способ достижения этой цели - честная игра. (Спецификации разных языков определяют, что представляет собой «функциональную правильность» и что может быть специфичным для реализации. Например, спецификация C# намного сложнее, чем спецификация C++ в отношении того, что соответствует спецификации и не разрешено чтобы сделать.) – LukeH

+0

@ LukeH согласен полностью. Не совсем ясно, что ОП задает в своем последнем параграфе. – EJP

+0

Спасибо! Извините, если моя формулировка сбивает с толку –

0

Это зависит от того, будут ли конкретные правила, которые последует за компилятором, произвести один и тот же вывод для двух разных входов.

Авторы компилятора не дают никаких гарантий в этом отношении. (Я не очень близко к эксперту, но я подозреваю, что проблема определения того, являются ли две программы одинаково идентичными, аналогична halting problem).

+0

Это неясно, это тот термин, который вы ищете. Но для многих случаев вы можете легко доказать эквивалентность. Опять же, всегда есть странные крайние случаи, вы хотите, чтобы аппаратный цикл на микроконтроллере, предназначенный для создания задержки, был оптимизирован? Наверное, нет .. –

+0

@KristopherMicinski: Неужели любая программа нетривиальной сложности быстро становится слишком сложной? –

+0

Неверно, рассмотрите петлевые подъемные и алгебраические оптимизации и более новые оптимизаторы всей программы. Вокруг этого создано целое поле исследований и процедур принятия компиляторов. Vectorizers, omega test и т. Д. ... все эти инструменты позволяют рассуждать о сложных шаблонах кода. Обычно вы не можете менять один алгоритм для другого, но вы можете сделать что-то еще сверх того, что увидит человек. –

0

В целом - нет, поскольку компилятор, предоставивший эту гарантию, сможет скомпилировать любую программу, которая не останавливается в простой бесконечной петле (while(true);).

Это будет решением проблемы остановки, которая невозможна для полного изучения языка.

0

В общем, да, компиляторы попытаются испустить один и тот же объектный код для данного входа для тех же настроек компилятора. Различные флаги, особенно уровни оптимизации, изменят выход.

Компилятор создает внутреннее представление кода, предоставленного ему («промежуточное представление», ИК), как правило, как дерево (http://lambda.uta.edu/cse5317/notes/node23.html), который затем манипулирует, чтобы создать лучший код. Ваш пример

int number; 
number = 2; 

VS.

int number = 2; 

является хорошим один: два фрагмента кода будет производить разные регистратуры, но компилятор будет преобразовывать первый, более сложный, IR во вторую. Современные компиляторы могут делать гораздо более сложные преобразования, упрощая код таким образом, чтобы человек находил очень сложным, но он не может этого делать в каждом случае - вы всегда сможете найти две семантически эквивалентные программы, которые не компилируются такой же код.

Для получения более подробной информации читайте http://en.wikipedia.org/wiki/Principles_of_Compiler_Design. Это увлекательная тема, и стоит хорошо прочитать ее.

Смежные вопросы