本篇 ShengYu 介紹 C/C++ #pragma pack 用法與範例。
現代的編譯器幾乎都會進行最佳化,所以有時候某資料結構佔用的 bytes 數可能不是你想像的,原因是因為編譯器會為了運行效能進行最佳化,如下列範例所示,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// g++ cpp-pragma-pack.cpp -o a.out
using namespace std;
struct CharCharInt { char c; char c2; int i; };
struct IntCharChar { int i; char c; char c2; };
struct CharIntChar { char c; int i; char c2; };
int main() {
struct CharCharInt charcharint;
struct IntCharChar intcharchar;
struct CharIntChar charintchar;
cout << "sizeof(CharCharInt) " << sizeof(charcharint) << '\n';
cout << "sizeof(IntCharChar) " << sizeof(intcharchar) << '\n';
cout << "sizeof(CharIntChar) " << sizeof(charintchar) << '\n';
return 0;
}
我的平台輸出如下,CharCharInt 手算的話應該為 6,但是編譯器進行最佳化時會變成 8,
而 CharIntChar 會因為順序關係而造成最佳化結果不同變成 12,1
2
3sizeof(CharCharInt) 8
sizeof(IntCharChar) 8
sizeof(CharIntChar) 12
通常在跨平台或資料結構的網路通訊中會需要資料對齊,
那麼如果要一定讓它強制對齊的話呢?Windows 與 Linux / macOS 作法不同,
在 Linux / macOS 下是這樣做,要加上 __attribute__((__packed__))
,適用於 GCC 編譯器,詳細用法可看這篇。
在 Windows 下是使用 #pragma pack
,這寫法原本只適用於 Visual C++ 編譯器,但後來 GCC 為了相容性也加入了這個語法的支援,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// g++ cpp-pragma-pack2.cpp -o a.out
using namespace std;
//#pragma pack(push)
//#pragma pack(1)
struct CharCharInt { char c; char c2; int i; };
struct IntCharChar { int i; char c; char c2; };
struct CharIntChar { char c; int i; char c2; };
int main() {
struct CharCharInt charcharint;
struct IntCharChar intcharchar;
struct CharIntChar charintchar;
cout << "sizeof(CharCharInt) " << sizeof(charcharint) << '\n';
cout << "sizeof(IntCharChar) " << sizeof(intcharchar) << '\n';
cout << "sizeof(CharIntChar) " << sizeof(charintchar) << '\n';
return 0;
}
我的平台輸出如下,1
2
3sizeof(CharCharInt) 6
sizeof(IntCharChar) 6
sizeof(CharIntChar) 6
以上就是 C/C++ pragma pack 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!
其它相關文章推薦
如果你想學習 C/C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ __attribute__((__packed__)) 用法與範例
C/C++ sizeof 用法與範例
C/C++ typedef 用法與範例
C/C++ define 用法與範例