编译器扩展与标准对齐控制

https://github.com/huihut/interview/issues/110
This commit is contained in:
huihut
2025-07-26 23:21:52 +08:00
parent cb34d14bc7
commit 48fd81d93b
2 changed files with 63 additions and 23 deletions

View File

@@ -290,24 +290,43 @@ assert( p != NULL ); // assert 不可用
* sizeof 对数组,得到整个数组所占空间大小。 * sizeof 对数组,得到整个数组所占空间大小。
* 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 ```cpp
#pragma pack(push) // 保存对齐状态 #include <cstddef>
#pragma pack(4) // 设定为 4 字节对齐 #include <iostream>
struct test #pragma pack(push, 1) // 最大对齐 1 字节,紧凑布局
{ struct PackedHeader {
char m1; uint16_t len; // offset 0
double m4; uint32_t id; // offset 2
int m3; };
#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
}
``` ```
### 位域 ### 位域

View File

@@ -295,25 +295,46 @@ assert( p != NULL ); // assert is not available
* sizeof For arrays - get the size of the entire array. * sizeof For arrays - get the size of the entire array.
* sizeof For pointers - get the size of the space occupied by the pointer itself. * 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 ```cpp
#pragma pack(push) // save alignment state #include <cstddef>
#pragma pack(4) // Set to 4 byte alignment #include <iostream>
struct test #pragma pack(push, 1) // Max alignment 1 byte (compact layout)
{ struct PackedHeader {
char m1; uint16_t len; // offset 0
double m4; uint32_t id; // offset 2
int m3; };
#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 ### Bit field