结构和对齐方式的大小
size of struct and alignment
根据这篇文章,结构的对齐是特定于实现的,这意味着不同的编译器将以不同的方式对齐结构中的成员,从而在编译器之间提供相同结构的不同大小。
但是,在此视频中,扬声器听起来像以下结构在编译器中的大小必须为 16 和 12:
#include <iostream>
struct C {
uint64_t x;
uint32_t y;
};
struct D {
uint32_t x;
uint32_t y;
uint32_t z;
};
int main() {
std::cout << sizeof(C) << std::endl;
std::cout << sizeof(D) << std::endl;
}
他们确实是 16 岁和 12 岁。
为什么他们必须是 16 岁和 12 岁? 不是 16 岁和 16 岁?
他们确实是 16 和 12。
它们具有此大小,给定:
- 您使用的编译器(和选项)
- 您的目标平台
- 代码中没有与结盟/包装相关的指令
对于您的视频,我想演讲者只是采用了给定的平台/工具链来开发他的示例。但是,一般来说,由于sizeof(T)
依赖于编译器/平台,因此std::atomic<T>::is_lock_free()
也依赖于编译器/平台。
例子
使用以下结构:
struct C {
uint64_t x;
uint32_t y;
};
不同的编译器和选项
- GCC 9.1"-M32":
sizeof(C) = 12
- MSVC x86 19.20:
sizeof(C) = 16
目标平台
- 适用于 x86-64 的 GCC 6.2:
sizeof(C) = 16
- 适用于 MSP430 的 GCC 6.2.1:
sizeof(C) = 12
对齐/包装指令
- GCC 9.1 x64 - 默认值:
sizeof(C) = 16
- GCC 9.1 x64 - 包装:
sizeof(C) = 12
- GCC 9.1 x64 - 对齐 128:
sizeof(C) = 128
为什么会有这些差异?
编译器可以在结构/类的任何字段之后自由添加未使用的位/字节。他们这样做是出于性能原因:在某些平台上,读/写验证某些对齐属性的多字节int
会更快(通常,N
字节int
的地址必须能被N
整除)。
通常,C++编译器在您背后执行低级优化很方便。有时您希望对此功能进行更多控制(原因的非详尽列表):
- 当您序列化将由其他程序读取的数据时(保存到文件,发送到网络)。
- 当内存使用比执行速度更重要时。
- 在多核和多线程程序中,控制CPU缓存行中有多少
struct
可以限制内核之间的缓存失效,从而提高执行速度。
这就是为什么编译器通常提供实用程序来控制它的原因。
TL;博士
对于给定的T
,sizeof(T)
"不必"成为任何东西。它依赖于编译器/平台,您通常可以使用特定的编译器指令覆盖它。
相关文章:
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 具有调整对齐方式的类型定义
- size_t的大小和对齐方式是否与ptrdiff_t相同?
- 逗号运算符在对齐方式中
- vcpkg:指定结构成员对齐方式
- 使用字节数组具有单字节对齐方式的结构是否安全
- C++对齐方式(何时使用对齐方式)
- 编译器会秘密增加结构的对齐方式吗?
- C++17 中函数参数的指针对齐方式
- 未在此范围内声明的对齐方式?
- 需要帮助以稍微不同的方式对齐连续的作业
- 如何控制 clang 格式新行中 lessless 的对齐方式
- C++ 编译器正在更改我的结构的对齐方式.我怎样才能防止这种情况
- 是否有符合标准的方法来确定非静态杆件的对齐方式?
- 重载运算符是具有较小默认对齐方式的新增运算符
- 结构和对齐方式的大小
- Sizeof 舍入到对齐方式,但编译器仍将对象放在剩余的字节中
- 自动热键:重新映射 MS Visio 的快捷方式,以将手动选择的对象对齐到顶部(好像按:"AlignTop")
- 是否可以让 std::vector<char> 使用选定的内存对齐方式分配内存
- 如何将值与给定的对齐方式对齐