2012-03-21 87 views
0

我会问一个关于编译器的问题,特别是他们如何工作。我相信编译器总是会编译成相同的机器代码,用于编写不同语法但代码相同的代码。这是真的?功能相似的代码是否被编译为相同的结果,而不管语法上的差异?有效的编译器每次都会编译完全相同的结果吗?

例如:

int number = 2; 

将编译为同样的事情:

int number; 
number = 2; 

while True: 

将是相同的(我在这里使用python作为例子):

while 1: 

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

谢谢!

+0

两个for循环怎么样? – 2012-03-21 00:47:00

+0

你是什么意思,“做同样的事情?”最后两个循环实际上做了不同的事情,因为即使它们循环五次,循环中的每个循环的值也都不相同。 – templatetypedef 2012-03-21 00:47:45

+1

在某些情况下,'for(int i = 0; i <5; i ++)'可能会被编译成与'for(int i = 1; i <= 5; i ++)'相同的目标代码,但是一般情况下你*不希望它,因为'我'会有不同的值范围。如果在循环内部使用'i',那么这种差异就很重要。 – 2012-03-21 00:49:14

回答

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效果,并以相同的方式解释。计算机是确定性的。

+0

计算机可能是确定性的,但编译器通常有很大的余地。只要最终的程序在功能上是正确的,那么几乎任何实现这一点的方式都是公平的游戏。 (不同的语言规范决定了什么是“功能正确性”,什么是“实现特定的”,例如,C#规范比C++规范严格得多,关于符合规范的程序是什么,并且不允许要做。) – LukeH 2012-03-21 01:22:04

+0

@LukeH完全同意。目前尚不清楚OP在最后一段中的要求。 – EJP 2012-03-21 01:27:17

+0

谢谢!对不起,如果我的措辞令人困惑 – 2012-03-21 10:44:12

0

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

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

+0

这是不可判定的,这是你正在寻找的术语。但是在很多情况下,你可以很容易地证明等价。再说一遍,总会有奇怪的边缘情况出现,你是否想要一个微控制器上的硬件环路 - 用于产生延迟 - 进行优化?可能不是.. – 2012-03-21 00:52:26

+0

@KristopherMicinski:当然,任何不平凡的复杂程序很快就变得难以推理了? – 2012-03-21 00:54:47

+0

完全不是,请考虑循环提升和代数优化,以及更新的整个程序优化器。编译器研究和决策程序的整个领域都围绕这一点建立起来了。 Vectorizers,omega测试等......所有这些工具都可以推理复杂的代码模式。通常不能将一种算法换成另一种算法,但是你可以做得比人类能看到的要多得多。 – 2012-03-21 01:23:21

0

一般来说 - 不,因为一个编译器给出了这个保证,可以编译任何不会暂停进入简单的无限循环的程序(while(true);)。

这样做会构成停止问题的解决方案,这对于完整的语言来说是不可能的。

0

一般来说,编译器会尝试为给定的输入发出相同的目标代码,编译器设置为。不同的标志,特别是优化级别,将改变输出。

编译器生成提供给它的代码的内部表示(“中间表示”,IR),通常以树形式(http://lambda.uta.edu/cse5317/notes/node23.html)然后它操纵它来生成更好的代码。你

int number; 
number = 2; 

int number = 2; 

的例子是一个很好的一个:两个代码段将产生不同的典藏,但是编译器将改变第一个,更复杂,IR进入第二个。现代编译器可以做更复杂的转换,以一种人类会觉得非常困难的方式来简化代码,但是他们无法在每种情况下都这样做 - 你总能找到两种语义上等价的程序,它们不会编译成相同的代码。

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

相关问题