*(__m128*)(&A) 和 (__m128)A 有什么区别

问题描述

*(B*)(&A)(B)A 有什么区别 我正在使用 simd 代码。但我遇到了问题。
我无法将自己的 vector4 类型转换为 __m128

所以我喜欢这个
这很好用

#define XMM128Float(VECTOR4FLOAT) *(__m128*)(&VECTOR4FLOAT)

Vector4<float> vec4{};
XMM128Float(&vec4) = _mm_mul_ps(XMM128Float(*this),XMM128Float(*this));

我想知道为什么 (__m128)vec4 不起作用....
它们之间有什么区别。

#define XMM128Float(VECTOR4FLOAT) *(__m128*)(&VECTOR4FLOAT)

template <>
[[nodiscard]] inline SIMD_CONSTEXPR auto Vector<4,float>::sqrMagnitude() const noexcept
{
    Vector<4,float> Result;
        
    XMM128Float(Result) = _mm_mul_ps(XMM128Float(*this),XMM128Float(*this));
    return Result.x + Result.y + Result.z + Result.w;
}

我的 SIMD 函数是这样写的。

我使用的是 MS BUILD 16 编译器

解决方法

*(B*)(&A)(B)A 的区别是什么

*(B*)(&A) 使用 addressof 运算符获取 A 命名的对象的地址,然后将该指针显式转换为另一个指针类型 B*,然后它通过2 间接转换指针。

(B)AA 命名的对象显式转换为 B 类型的新对象。

我想知道为什么 (__m128)vec4 不起作用....

您不能将类类型 A 的值转换为另一种类型 B,除非您为 A 定义了可以转换为类型 B 的转换运算符或另一种可转换为 B 的类型(或者除非 B 也是一个类并且具有接受 A 参数的转换构造函数或另一种可转换为 A 的类型)-请注意,仅一个这样的用户定义的转换可以在一个转换序列中使用;其他转换必须是标准转换。


1 不要在 C++ 中使用显式转换,即 C 风格的强制转换。改用特定的 static_castreinterpret_castconst_cast

2 请注意,根据所涉及的类型,通过重新解释的指针访问对象通常可能导致未定义的行为。仅在特定情况下才允许。请查阅您的编译器手册以了解 __m128 是否属于这种情况。

附言避免不必要的宏。您编写的内容可以定义为内联函数。