2012-03-21 84 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。這是一個引人入勝的話題,值得一讀。

相關問題