Как работает компиляция циклических зависимостей? - PullRequest
15 голосов
/ 13 июня 2010

Я сделал пример на Java, но я думаю (не проверял), что он работает на других (всех?) Языках.

У вас есть 2 файла. Сначала M.java:

public class MType {
    XType x;
    MType() {x = null;}
}

Второй, другой файл (в том же каталоге), XType.java:

public class XType {
   MType m;
   public XType(MType m) {this.m = m;}
}

Хорошо, это плохое программирование, но если вы запускаете javac XType, оно компилируется: компилируется даже MType, потому что XType нуждается в этом. Но ... MType нужно XType ... как это работает? Как компилятор узнает, что происходит?

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

Я спрашиваю, потому что я пишу прекомпилятор, и я хотел бы справиться с этой ситуацией.

Ответы [ 2 ]

6 голосов
/ 13 июня 2010

Вам необходимо пройти 2 прохода или многоходовой подход :

Языки, такие как Java, требуют многопроходного компилятора, так как определение x не требуется перед использованием:

public class Example {  
public static void main(String [] args) {
    assert(x==0);           
    x++;
    assert(x==1);
}
static int x=0;
}

Существуют различные подходы, например, вы можете сделать следующее:

На первом проходе можно искать все объявления переменных, на втором - объявления методов и т. Д., Пока последний проход не использует всю эту информацию для компиляции окончательного кода.

4 голосов
/ 13 июня 2010

Первый файл не должен ничего знать о XType, за исключением того, что он является типом, и аналогично для MType во втором файле. Кроме того, в Java все объекты имеют одинаковый размер (потому что все доступно через ссылки), поэтому размер объекта не требуется. Это не так в других языках - ваш код, как он есть, не будет компилироваться, например, в C ++ (без синтаксиса языка).

...