微软官方建议:在类内部使用XMFLOATn来存储和表示向量。
理由是:XMVECTOR即__m128类型需要按16字节对齐,这对于全局变量和局部变量是自动实现的,而类内属性却不是。
根据C++默认内存对齐规则,结构体内部会自动实现内存对齐,即结构体中每个属性所处内存的偏移量等于其大小的整数倍。
我查看了__m128的定义,发现其使用 " align(16) " 来表明其所占字节为16的整数倍,那么为什么类内的__m128属性不会实现内存对齐?
我查阅相关资料,有一个帖子说:“该类不是在对齐地址处创建的,因此即使 XM* 成员在 16 字节边界上对齐,父级的对齐方式也会错位它们,从而导致崩溃”。
如果类中的属性会因为类的起始地址导致错位,那么像常见的结构体,怎样保证只要 “结构体中属性内存的偏移量等于其大小的整数倍” 就有 “结构体中属性内存的起始地址是其大小的整数倍”。
Direct3D在类中为什么要使用XMFLOATn而非XMVECTOR?
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
2条回答 默认 最新
K_n_i_g_h_t_1990 2023-11-25 13:57关注在C++中,类内部的内存对齐和结构体的内存对齐规则是有区别的。在类内部,如果类中包含有向量类型(如
__m128)这样需要特殊对齐的成员,需要手动进行对齐处理。在默认情况下,C++类的内存对齐是根据其中包含的成员的最大对齐要求来决定的。因此,如果类内有成员的对齐要求超过默认对齐(通常是4或8字节),就需要手动设置对齐方式。
对于结构体,如果结构体中的成员有特殊的对齐要求,整个结构体的对齐方式通常会被设置为其中最大的成员对齐要求。这意味着结构体中每个成员的内存偏移量等于其大小的整数倍,但整个结构体的起始地址不一定是其大小的整数倍。
以下是一个例子,展示了如何使用
alignas关键字来手动设置类内部和结构体的对齐方式:#include <iostream> #include <immintrin.h> class MyClass { public: alignas(16) __m128 vector; // 使用 alignas(16) 来设置对齐方式 int integer; // 其他成员... }; struct MyStruct { alignas(16) int integer; // 使用 alignas(16) 来设置对齐方式 float floatingPoint; // 其他成员... }; int main() { std::cout << "Size of MyClass: " << sizeof(MyClass) << std::endl; std::cout << "Size of MyStruct: " << sizeof(MyStruct) << std::endl; return 0; }在上述代码中,
alignas(16)用于指定__m128或int的对齐方式为16字节。这样就能确保类或结构体中的成员按照期望的对齐方式排列,避免了在类内部或结构体中因为对齐问题而导致的错误。本回答被题主选为最佳回答 , 对您是否有帮助呢?评论 打赏 举报解决 1无用