這次聊的話題主要是和硬件體系有關的。比如你的程序需要支持不同類型的CPU(x86、SPARC、PowerPC),或者是同種類型不同字長的CPU(比如x86和x86-64),這時候你就需要關心一下硬件體系的問題。
★基本類型的大小
C++中基本類型的大小(占用的字節數)會隨著CPU字長的變化而變化。所以,假如你要表示一個int占用的字節數,千萬不要直接寫“4”(順便說一下,直接寫“4”還犯了Magic Number的大忌,詳見這裡),而應該寫“sizeof(int)”;反過來,如果你要定義一個大小必須為4字節的有符號整數,也不要直接用int,要用預先typedef好的定長類型(比如boost庫的int32_t、ACE庫的ACE_INT32、等)。
差點忘了,指針的大小也有上述的問題,也要小心。
★字節序
如果你沒聽說過“字節序”這玩意兒,請看“維基百科”。通俗地打個比方,在一個大尾序的機器上有一個4字節的整數0x01020304,通過網絡或者文件傳到一台小尾序的機器上就會變成0x04030201;據說還有一種中尾序的機器(不過我沒接觸過),上述整數會變成0x02010403。
如果你編寫的應用程序中涉及網絡通訊,一定要在記得進行主機序和網絡序的翻譯;如果涉及跨機器傳輸二進制文件,也要記得進行類似的轉換。
★內存對齊
如果你不曉得“內存對齊”是什麼東東,請看“維基百科”。簡單來說,出於CPU處理上的性能考慮,結構體中的數據不是緊挨著的,而是要空開一些間隔。這樣的話,結構體中每個數據的地址正好都是某個字長的整數倍。
由於C++標准中沒有定義內存對齊的細節,因此,你的代碼也不能依賴對齊的細節。凡是計算結構體大小的地方,都老老實實寫上sizeof()。
有些編譯器支持#pragma pack預處理語句(可以用來修改對齊字長),不過這種語法不是所有編譯器都支持,要慎用。
★移位操作
對於有符號整數的右移操作,有些系統默認使用算數右移(最高的符號位不變),有些默認使用邏輯右移(最高的符號位補0)。所以,不要對有符號整數進行右移操作。順便說一下,即使沒有移植性問題,代碼中也盡量不要使用移位運算操作,可讀性太差。
下一個帖子,准備聊一下“操作系統相關的跨平台問題”。