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