2011-08-26 245 views
2

我懷疑爲什麼會發生這樣的情況:不同的編譯器會給同一個C程序提供不同的輸出。如果存在標準C,那麼爲什麼這些着名的編譯器不會完全使用它。 輸出的差異是由16位32位編譯器引起的,所以這些問題會導致差異。爲什麼不同的C編譯器爲C程序提供不同的輸出?

+1

也許如果你發佈了導致不同編譯器給出不同結果的確切代碼,我們可以告訴你爲什麼。你的邏輯很可能是錯誤的。 – Daniel

+0

在不同的編譯器上試試這個:a = a ++ + ++ a; –

回答

4

語言標準爲實現留下了幾個自由度。首先,即使程序正確執行,其行爲可能依賴於實現定義的語言功能。例如,對於基本整數類型,不同的實現可以具有不同的範圍。

其次,程序可能會被打破。在這種情況下,一個破碎的程序是依賴於未定義或未被該語言指定的行爲的程序。該計劃似乎以某種方式「發揮作用」,但其實際行爲將取決於不可預測的因素,因此將不一致。

實踐表明,在許多(如果不是大多數)情況下,當人們抱怨行爲不一致的C程序,它們實際上沒有意識到,他們正在處理一個破碎的程序。

10

你有例子嗎?

的語言規範,但它的很多方面都實現定義甚至是不確定的。

例如,這樣的:

printf("sizeof (int) = %u\n", (unsigned)sizeof (int)); 

將在不同系統上打印不同的數字,這取決於int有多大。

0

在大多數情況下,它當程序員使用了未定義行爲和編譯器來嘗試猜你的意思是。

的另一個潛在問題的例子:C++ 0x中剛剛得到批准,但並未公開提供的最終草案。只要它變得可用,一些編譯器可能會在其他人之前添加支持。

解決方案的一部分:許多編譯器都有一種方法來編譯到某個規範。例如,對於GCC,您可以使用「gcc programname.c -ansi」進行編譯,以確保您的代碼符合ANSI標準。這將確保一致性。

2

C中有很多東西是實現定義的。這意味着創建編譯器的人可以選擇他們想要如何處理這些情況。一般來說,爲了便於攜帶,在大多數情況下最好不要依賴未定義的行爲,即使大多數或所有編譯器都以相同的方式處理它。如果你提供了一些不同的編譯器對待不同的代碼,也許我們可以告訴你他們爲什麼這樣做以及如何解決它。

未定義行爲的一個例子是引用一個未初始化的變量是這樣的:

int *a; 
printf("%d", *a); 

在大多數實現中,你會看到一些垃圾整數,這並不意味着任何東西(一個警告一起)。無論存儲在a指向的內存位置中的值是什麼,然而,在技術上,實現可能已經指定引用一個未初始化的變量總是會給0(或類似的東西)。原因並非如此,因爲實施起來要困難得多。儘管如此,你仍然不應該指望在a指向的內存位置發生任何事情。它可能會或可能不是你得到的。

相關問題