一个有效的编译器每次编译成完全相同的结果?

时间:2012-03-21 00:44:25

标签: .net compiler-construction interpreter

我会问一个关于编译器的问题,特别是它们是如何工作的。我相信编译器总是会编译为相同的机器代码,以便在语法上以不同的方式编写代码但执行相同的操作。这是真的?无论语法差异如何,功能相似的代码都会编译成相同的结果吗?

例如:

int number = 2;

将编译为:

int number;
number = 2;

while True:

将与(我在这里使用python作为示例)相同:

while 1:

我对.net编译器和解释器特别感兴趣。 JIT编译器每次都“及时”编译到同一个东西吗?像Python解释器这样的解释器每次都“解释”代码完全相同吗?

谢谢!

4 个答案:

答案 0 :(得分:1)

int number = 2;

将编译为:

int number; number = 2;

可能但不一定。 NB在许多语言中声明根本不生成任何代码。

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

与:

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

当然不是!不同的语义!

注意,这不是'效率'的考虑因素。

  

JIT编译器每次都“及时”编译到同一个东西吗?   像Python解释器这样的解释器“解释”代码   每次完全相同?

现在你似乎在问一个完全不同的问题。相同的源代码总是以相同的方式编译,模数JIT效果,并以相同的方式解释。计算机是确定性的。

答案 1 :(得分:0)

这取决于编译器遵循的特定规则是否会为两个不同的输入产生相同的输出。

编译器的作者在这方面没有做出任何保证。 (我与专家没什么关系,但我怀疑确定两个程序是否明显相同的问题与halting problem相似。

答案 2 :(得分:0)

一般情况下 - 不,因为提供该保证的编译器能够编译任何不会停止进入简单无限循环(while(true);)的程序。

这样做可以解决暂停问题,这对于图灵完整的语言是不可能的。

答案 3 :(得分:0)

通常,是的,编译器会尝试为相同的编译器设置为给定的输入发出相同的目标代码。不同的标志,尤其是优化级别,将改变输出。

编译器生成提供给它的代码的内部表示('中间表示',IR),通常作为树(http://lambda.uta.edu/cse5317/notes/node23.html),然后它操纵产生更好的代码。

的例子
int number;
number = 2;

VS

int number = 2;

是一个很好的:两个代码片段会产生不同的IR,但编译器会将第一个更复杂的IR转换为第二个。现代编译器可以进行更复杂的转换,以人类发现非常困难的方式简化代码,但是它们无法在每种情况下都能实现 - 你总是能够找到两个语义上相同的程序,这些程序不能编译到相同的代码。

更多,请阅读http://en.wikipedia.org/wiki/Principles_of_Compiler_Design。这是一个引人入胜的话题,值得一读。