除了在學習 C 語言結構體字節對齊時,做練習題的時候碰到過,在幾年的工作中,一直沒有找到 #pragma pack 的使用場景。最近實現一套 C/S 系統的內部通信,在讀取網絡數據時,碰到了字節對齊引起的問題。具體如下:
Server 用 Java 實現,發送數據是採用 WriteInt、WriteShort 等方式,並沒有考慮字節對齊的問題(Java 也的確無需考慮)。我的最初設計是,定義一個對應的結構體指針,然後分別讀取結構體中的各個字段,但是發現得到的數據不對。經過仔細比對,發現原因是數據錯位。仔細思考纔想到,是字節對齊引起的。
定義的結構體如下:
typedef struct tagTEST {
uint32_t i;
uint16_t j;
uint32_t k;
......
}TEST_S;
使用該指針指向網絡數據包時,i 和 j 是對的,但是從 k 以後就開始錯位。原因就是系統默認按照 4 字節對齊(這個說法不全對,如果是 uint32_t 和 uint64_t 在一起,uint32_t 後也會空餘 4 字節),所以 j 和 k 之間有 2 個字節的填充。此時指向數據包,自然就發現錯位了。解決辦法也很簡單,使用 #pragma pack 強制按照你所需要的字節對齊即可。
後來想到,linux 中的 ip.h、tcp.h 也應該指定強制 1 字節對齊,但是看了源碼,並沒有使用 #pragma。why?
#pragma 更多的參數請百度之。