2014-01-30 29 views
2

我們剛剛偶然發現了Android版本的應用程序中的錯誤,這是由iOS和Android上的編譯器差異造成的。好奇的是,如果有人能夠解釋這種差異以及如何使Android本機C編譯器像iOS一樣工作。這是一個簡化版本的問題。針對iOS和Android開發的C編譯器差異

double zone = -7/24.0; 
char command[80] = { '\0' }; 

//其他的東西

command[7] = zone * 24.0; 

忽略上述可能的舍入誤差。這是一個簡單的例子。

在iOS上,命令[7]獲取值-7。這是我所期望的,因爲在執行分配時應該自動從double轉換爲char(或int)。

在Android上,使用本地C編譯器,我們將0放入命令[7]。如果我們明確地施展它就好像

command[7] = (int)(zone * 24.0); 

然後它獲得與iOS相同的結果。

有誰知道爲什麼兩個編譯器可能會生成不同的代碼?如果Android上有一個編譯器標誌使編譯器像iOS一樣運行?該應用程序已經在iOS上進行了廣泛的測試,我們對這個問題有點懷疑。

回答

1

在您的Android C實現中,char是無符號的,並且從doublechar的-7的轉換產生零。 (當該值不能在目標類型來表示這種轉換的行爲不是由C標準定義。)

在iOS中,char簽訂,和-7至doublechar轉換產生-7。

編譯器可能有一個-fsigned-char開關,將使char簽名,或者您可以將char command[80]…更改爲signed char command[80]…

這就解釋了爲什麼command[7] = (int)(zone * 24.0);取得了預期的效果:

  • 當你將其分配給command[7]之前投的結果int,-7在double轉化爲-7 int。然後將這個int轉換爲無符號的char。該轉換由C標準定義,結果爲CHAR_MAX + 1-7(典型C實現中爲249,無符號char)。這在iOS(-7)和Android(249)上並不是相同的結果,但它們用相同的位表示。據推測,他們行爲相同,無論你進一步使用它們。
+0

將-fsigned-char標誌添加到Android.mk確實解決了問題。非常感謝分析。 – btschumy