爲32位/ 64位移植的典型缺陷是:
由程序員那的sizeof(無效*)== 4 *的sizeof(char)的隱含的假設。 如果你正在做這個假設,例如以這種方式分配數組(「我需要20個指針,因此我分配80個字節」),您的代碼在64位上斷開,因爲它會導致緩衝區溢出。
「小貓殺手」,int x =(int)&something; (並且相反,void * ptr =(void *)some_int)。再次假設sizeof(int)== sizeof(void *)。這不會導致溢出,但會丟失數據 - 指針的高32位,即。
這兩個問題是一類稱爲混疊型(兩種類型之間的二進制表示水平假設身份/互換性/等效)的,並且這樣的假設是常見的;像在UN * X上一樣,假設time_t,size_t,off_t是int,或者在Windows上,HANDLE,void *和long可互換等等。
關於數據結構/堆棧空間使用的假設好)。在C/C++代碼中,局部變量分配在堆棧上,由於下面的點,因此在32位和64位模式之間使用的空間不同,並且由於傳遞參數的不同規則(通常在堆棧上有32位x86,64位x86部分在寄存器中)。剛剛擺脫32位默認堆棧大小的代碼可能會導致64位堆棧溢出崩潰。 這是相當容易發現作爲崩潰的原因,但取決於可能難以解決的應用程序的可配置性。 32位和64位代碼之間(由於不同的代碼尺寸/高速緩存足跡,或不同的存儲器訪問特徵/圖案,或不同的調用約定)
時間差異可能會破壞「校準」。說,for(int i = 0; i < 1000000; ++ i)sleep(0);很可能將會有不同的時間對32位和64位...
最後,ABI(應用程序二進制接口)。通常,64位環境中存在兩個主要的「分支」,IL32P64(Win64使用的是--int和long是int32_t,只有uintptr_t/void *是uint64_t,根據來自)和LP64(UN * X使用的是什麼 - int是int32_t,long是int64_t和uintptr_t/void *是uint64_t),但也存在不同對齊規則的「細分」 - 一些環境假設長,浮動或雙對齊,而其他人則假定它們以四個字節的倍數對齊。在32位Linux中,它們全部以四個字節對齊,而在64位Linux中,它們以八字節倍數浮動對齊四位,長兩位。 這些規則的結果是,即使數據類型聲明完全相同,在很多情況下,bith sizeof(struct {...})和結構/類成員的偏移量在32位和64位環境之間也是不同的。 除了影響陣列/向量分配之外,這些問題還會影響數據輸入/輸出。通過文件 - 如果32位應用程序編寫例如struct {char a; int b; char c,long d;雙e}到同一個應用程序重新編譯爲64位的文件讀入,結果將不會完全符合所希望的。 剛剛給出的例子只是關於語言原語(char,int,long等),但當然會影響各種平臺相關/運行時庫數據類型,無論size_t,off_t,time_t,HANDLE,本質上是任何非平凡的結構/聯合/ class ... - 所以這裏的錯誤空間很大,
然後還有更低層次的差異,用於手動優化組裝(SSE/SSE2/...); 32位和64位具有不同的(數量)寄存器,不同的參數傳遞規則;所有這些都強烈地影響着這種優化如何執行,並且很可能如在32位模式下提供最佳性能的SSE2代碼將需要重寫/需要增強以提供最佳性能的64位模式。對於32位和64位,還有代碼設計約束條件非常不同,尤其是在內存分配/管理方面;一個經過仔細編碼的應用程序「最大限度地利用mem可以獲得32位」將具有複雜的邏輯,如何/何時分配/釋放內存,內存映射文件使用率,內部緩存等 - 其中大部分將在64位上是不利的,你可以「簡單地」利用巨大的可用地址空間。這樣的應用程序可能會重新編譯爲64位就好了,但在那裏執行比一些「古老的簡單的不推薦的版本」,它沒有所有的最大化 - 32位窺視孔優化。因此,最終它也是關於增強/增益的,這就是更多的工作,部分是編程,部分是設計/需求。即使你的應用在32位和64位環境中都乾淨地重新編譯,並在兩者上都得到驗證,它實際上是從64位受益?是否可以/應該對代碼邏輯進行更改,以使其在64位中執行更多/更快的運行?你能做這些改變而不破壞32位向後兼容性嗎?對32位目標沒有負面影響?增強功能在哪裏,你能獲得多少? 對於大型商業項目,這些問題的答案往往是路線圖上的重要標記,因爲您的出發點是一些現有的「貨幣制造商」...
awsome anwser :)只是我在找:) – 2013-02-21 13:12:33
@FredrikBostonWestman那麼你應該接受它! – gsamaras 2015-04-04 15:41:49