VS2019,发布,x86.
template <int i> float get() const {
int f = _mm_extract_ps(fmm, i);
return (float const&)f;
}
Run Code Online (Sandbox Code Playgroud)
使用return (float&)f;编译器时使用
extractps m32, ...
movss xmm0, m32
Run Code Online (Sandbox Code Playgroud)
.正确的结果
使用return (float const&)f;编译器时使用
extractps eax, ...
movd xmm0, eax
Run Code Online (Sandbox Code Playgroud)
.错误的结果
T&和T const&首先是T然后是const的主要思想.Const只是程序员的某种协议.你知道你可以解决它.但汇编代码中没有任何const,但是类型为float IS.我认为对于float和float const而言它必须是汇编中的浮点表示(cpu寄存器).我们可以使用中间int reg32,但最终解释必须是float.
而此时它看起来像回归,因为这之前工作正常.并且在这种情况下使用float也绝对是奇怪的,因为我们不应该考虑浮动const和安全性而是浮动的临时变量并且确实值得怀疑.
微软回答:
嗨Truthfinder,感谢自成一体的复制品.碰巧,这种行为实际上是正确的.正如我的同事@Xiang Fan [MSFT]在内部电子邮件中所述:
由[a c-style cast]执行的转换尝试以下序列:(4.1) - const_cast(7.6.1.11),(4.2) - static_cast(7.6.1.9),(4.3) - static_cast后跟const_cast ,(4.4) - reinterpret_cast(7.6.1.10)或(4.5) - reinterpret_cast后跟const_cast,
如果转换可以用上面列出的多种方式解释,则使用列表中首先出现的解释.
所以在你的情况下,(const float&)被转换为static_cast,其效果是"初始化表达式被隐式转换为类型为"cv1 T1"的prvalue.应用临时实现转换并将引用绑定到结果".
但在另一种情况下,(float&)被转换为reinterpret_cast,因为static_cast无效,这与reinterpret_cast(&operand)相同.
您正在观察的实际"错误"是一个强制转换:"将浮点型值"1.0"转换为等效的int-typed值"1"",而另一个强制转换说"将1.0的位表示形式转换为一个浮点数,然后将这些位解释为int".
出于这个原因,我们建议不要使用c风格的演员表.
谢谢!
MS论坛链接:https://developercommunity.visualstudio.com/content/problem/411552/extract-ps-intrinsics-bug.html
有任何想法吗?
PS我真正想要的是什么:
float val …Run Code Online (Sandbox Code Playgroud)