From 48fd81d93b562df1c71e04e31110e8c69ddb4fdd Mon Sep 17 00:00:00 2001 From: huihut Date: Sat, 26 Jul 2025 23:21:52 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=99=A8=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E4=B8=8E=E6=A0=87=E5=87=86=E5=AF=B9=E9=BD=90=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/huihut/interview/issues/110 --- README.md | 41 ++++++++++++++++++++++++++++++----------- README_en.md | 45 +++++++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 92f615f..a7f175c 100644 --- a/README.md +++ b/README.md @@ -290,24 +290,43 @@ assert( p != NULL ); // assert 不可用 * sizeof 对数组,得到整个数组所占空间大小。 * sizeof 对指针,得到指针本身所占空间大小。 -### #pragma pack(n) +### 编译器扩展与标准对齐控制 -设定结构体、联合以及类成员变量以 n 字节方式对齐 +* 编译器扩展:`#pragma pack(n)`,将随后定义的 `struct`/`class`/`union` 的成员最大对齐限制为 n 字节。 +* 标准对齐控制: + * `alignas(k)`,要求类型或变量至少按 k 字节对齐(向上取整到 ≥ 自然对齐)。 + * `alignof(T)`,获取类型 T 的自然对齐要求(编译时常量)。 -#pragma pack(n) 使用 +特性 |#pragma pack|alignas +--------|--------------|------------ +标准化 |❌ 编译器扩展 | ✅ C++11标准 +对齐方向|⬇️ 只能减小对齐| ⬆️ 只能增大对齐 +可移植性|❌ 编译器依赖 | ✅ 跨平台 +作用范围|🔄 影响整个结构| 🎯 可针对单个成员 +性能影响|⚠️ 可能降低内存访问速度| ⚠️ 过度对齐浪费空间 + +使用 ```cpp -#pragma pack(push) // 保存对齐状态 -#pragma pack(4) // 设定为 4 字节对齐 +#include +#include -struct test -{ - char m1; - double m4; - int m3; +#pragma pack(push, 1) // 最大对齐 1 字节,紧凑布局 +struct PackedHeader { + uint16_t len; // offset 0 + uint32_t id; // offset 2 +}; +#pragma pack(pop) + +struct alignas(8) Align8 { + double value; // offset 0, 占 8 字节 + int flag; // offset 8 }; -#pragma pack(pop) // 恢复对齐状态 +int main() { + std::cout << "PackedHeader size: " << sizeof(PackedHeader) << "\n"; // 6 + std::cout << "Align8 size: " << sizeof(Align8) << "\n"; // 16 +} ``` ### 位域 diff --git a/README_en.md b/README_en.md index 26dda64..283488f 100644 --- a/README_en.md +++ b/README_en.md @@ -295,25 +295,46 @@ assert( p != NULL ); // assert is not available * sizeof For arrays - get the size of the entire array. * sizeof For pointers - get the size of the space occupied by the pointer itself. -### #pragma pack(n) +### Compiler Extensions vs Standard Alignment Control -Set structure, union, and class member variables to be n-byte aligned +* Compiler Extension `#pragma pack(n)`, restricts the maximum alignment of members in subsequently defined `struct`/`class`/`union` to n bytes. +* Standard Alignment Control: + * `alignas(k)`, requires types or variables to be aligned to at least k bytes (rounds up to ≥ natural alignment). + * `alignof(T)`, gets the natural alignment requirement of type T (compile-time constant). -#pragma pack (n) use +Feature | `#pragma pack` | `alignas` +----------------|-------------------------|--------------------- +Standardization | ❌ Compiler Extension | ✅ C++11 Standard +Alignment Direction | ⬇️ Only decreases alignment | ⬆️ Only increases alignment +Portability | ❌ Compiler Dependent | ✅ Cross-platform +Scope | 🔄 Affects entire struct | 🎯 Per-member control +Performance Impact | ⚠️ May reduce memory access speed | ⚠️ Over-alignment wastes space + +#### Usage Examples ```cpp -#pragma pack(push) // save alignment state -#pragma pack(4) // Set to 4 byte alignment +#include +#include -struct test -{ - char m1; - double m4; - int m3; +#pragma pack(push, 1) // Max alignment 1 byte (compact layout) +struct PackedHeader { + uint16_t len; // offset 0 + uint32_t id; // offset 2 +}; +#pragma pack(pop) + +struct alignas(8) Align8 { // Force 8-byte alignment + double value; // offset 0 (8 bytes) + int flag; // offset 8 }; -#pragma pack(pop) // Restore alignment -``` +int main() { + std::cout << "PackedHeader size: " + << sizeof(PackedHeader) << "\n"; // Output: 6 + + std::cout << "Align8 size: " + << sizeof(Align8) << "\n"; // Output: 16 +} ### Bit field