编译循环依赖关系如何工作?

时间:2010-06-13 16:02:30

标签: compiler-construction circular-dependency

我用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 个答案:

答案 0 :(得分:6)

您需要采用2遍或multi-pass方法:

  

像Java这样的语言需要多次传递编译器,因为在使用之前不需要定义x:

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

有各种方法,例如您可以执行以下操作:

第一遍可以查找所有变量声明,第二遍可以查找方法声明等,直到最后一遍使用所有这些信息来编译最终代码。

答案 1 :(得分:4)

第一个文件不需要知道任何关于XType的信息,除了它是一个类型,并且类似于第二个文件中的MType。此外,在Java中,所有对象实际上都是相同的大小(因为所有对象都是通过引用访问的),因此不需要对象的大小。在其他语言中情况并非如此 - 例如,您的代码无法在C ++中编译(例如语言语法)。