C/C++ pragma pack 用法與範例

本篇 ShengYu 介紹 C/C++ #pragma pack 用法與範例。

現代的編譯器幾乎都會進行最佳化,所以有時候某資料結構佔用的 bytes 數可能不是你想像的,原因是因為編譯器會為了運行效能進行最佳化,如下列範例所示,

cpp-pragma-pack.cpp
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
#include <iostream>
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
3
sizeof(CharCharInt) 8
sizeof(IntCharChar) 8
sizeof(CharIntChar) 12

通常在跨平台或資料結構的網路通訊中會需要資料對齊,
那麼如果要一定讓它強制對齊的話呢?Windows 與 Linux / macOS 作法不同,
在 Linux / macOS 下是這樣做,要加上 __attribute__((__packed__)),適用於 GCC 編譯器,詳細用法可看這篇
在 Windows 下是使用 #pragma pack,這寫法原本只適用於 Visual C++ 編譯器,但後來 GCC 為了相容性也加入了這個語法的支援,

cpp-pragma-pack2.cpp
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
#include <iostream>
using namespace std;

//#pragma pack(push)
//#pragma pack(1)
#pragma pack(push, 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; };
#pragma pack(pop)

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
3
sizeof(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 用法與範例