Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ VC中的Bug++;14.0(2015)编译器?_C++_Visual Studio - Fatal编程技术网

C++ VC中的Bug++;14.0(2015)编译器?

C++ VC中的Bug++;14.0(2015)编译器?,c++,visual-studio,C++,Visual Studio,我遇到了一些问题,这些问题只发生在x86版模式下,而不是x64版模式下或任何调试模式下。我使用以下代码成功地重现了该错误: #include <stdio.h> #include <iostream> using namespace std; struct WMatrix { float _11, _12, _13, _14; float _21, _22, _23, _24; float _31, _32, _33, _34; floa

我遇到了一些问题,这些问题只发生在x86版模式下,而不是x64版模式下或任何调试模式下。我使用以下代码成功地重现了该错误:

#include <stdio.h>
#include <iostream>
using namespace std;

struct WMatrix {
    float _11, _12, _13, _14;
    float _21, _22, _23, _24;
    float _31, _32, _33, _34;
    float _41, _42, _43, _44;

    WMatrix(float f11, float f12, float f13, float f14,
            float f21, float f22, float f23, float f24,
            float f31, float f32, float f33, float f34,
            float f41, float f42, float f43, float f44) :
        _11(f11), _12(f12), _13(f13), _14(f14),
        _21(f21), _22(f22), _23(f23), _24(f24),
        _31(f31), _32(f32), _33(f33), _34(f34),
        _41(f41), _42(f42), _43(f43), _44(f44) {
    }
};

void printmtx(WMatrix m1) {
    char str[256];
    sprintf_s(str, 256, "%.3f, %.3f, %.3f, %.3f", m1._11, m1._12, m1._13, m1._14);
    cout << str << "\n";
    sprintf_s(str, 256, "%.3f, %.3f, %.3f, %.3f", m1._21, m1._22, m1._23, m1._24);
    cout << str << "\n";
    sprintf_s(str, 256, "%.3f, %.3f, %.3f, %.3f", m1._31, m1._32, m1._33, m1._34);
    cout << str << "\n";
    sprintf_s(str, 256, "%.3f, %.3f, %.3f, %.3f", m1._41, m1._42, m1._43, m1._44);
    cout << str << "\n";
}

WMatrix mul1(WMatrix m, float f) {
    WMatrix out = m;
    for (unsigned int i = 0; i < 4; i++) {
        for (unsigned int j = 0; j < 4; j++) {
            unsigned int idx = i * 4 + j; // critical code
            *(&out._11 + idx) *= f; // critical code
        }
    }
    return out;
}

WMatrix mul2(WMatrix m, float f) {
    WMatrix out = m;
    unsigned int idx2 = 0;
    for (unsigned int i = 0; i < 4; i++) {
        for (unsigned int j = 0; j < 4; j++) {
            unsigned int idx = i * 4 + j; // critical code
            bool b = idx == idx2; // critical code
            *(&out._11 + idx) *= f; // critical code
            idx2++;
        }
    }
    return out;
}


int main() {
    WMatrix m1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
    WMatrix m2 = mul1(m1, 0.5f);
    WMatrix m3 = mul2(m1, 0.5f);

    printmtx(m1);
    cout << "\n";
    printmtx(m2);
    cout << "\n";
    printmtx(m3);

    int x;
    cin >> x;
}
正确的输出应该是

1.000, 2.000, 3.000, 4.000
5.000, 6.000, 7.000, 8.000
9.000, 10.000, 11.000, 12.000
13.000, 14.000, 15.000, 16.000

0.500, 1.000, 1.500, 2.000
2.500, 3.000, 3.500, 4.000
4.500, 5.000, 5.500, 6.000
6.500, 7.000, 7.500, 8.000

0.500, 1.000, 1.500, 2.000
2.500, 3.000, 3.500, 4.000
4.500, 5.000, 5.500, 6.000
6.500, 7.000, 7.500, 8.000

我错过什么了吗?或者它实际上是编译器中的一个bug?

这只影响32位编译器;无论优化设置如何,x86-64版本都不受影响。但是,无论是针对速度(/O2)还是大小(/O1)进行优化,您都可以在32位构建中看到问题。正如您所提到的,在调试禁用优化的构建时,它可以按预期工作

温梅尔关于改变包装的建议虽然准确,但并没有改变行为。(以下代码假设
WMatrix
的包装正确设置为1)

我不能在VS 2010中复制它,但我可以在VS 2013和2015中复制。我没有安装2012。不过,这足以让我们分析两个编译器生成的目标代码之间的差异

以下是VS 2010中mul1的代码(“工作”代码):
(实际上,在许多情况下,编译器在调用站点内联了来自此函数的代码。但是编译器仍然会输出反汇编文件,其中包含在内联之前为各个函数生成的代码。这就是我们在这里看到的,因为它更混乱。无论它是否已内联。)

PUBLIC mul1
_文本段
_m$=8;尺寸=64
_f$=72;尺寸=4
mul1程序
___$ReturnUdt$=eax
推动esi
推式电子数据交换
; WMatrix out=m;
mov-ecx,16;00000010H
lea esi,DWORD PTR m$[esp+4]
电子数据交换
代表movsd
; for(无符号整数i=0;i<4;i++)
; {
;for(无符号整数j=0;j<4;j++)
;    {
;unsigned int idx=i*4+j;//关键代码
;*(&out._11+idx)*=f;//关键代码
movss xmm0,DWORD PTR[eax]
cvtps2pd xmm1,xmm0
movss xmm0,DWORD PTR _f$[esp+4]
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax],xmm1
movss xmm1,DWORD PTR[eax+4]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+4],xmm1
movss xmm1,DWORD PTR[eax+8]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+8],xmm1
movss xmm1,DWORD PTR[eax+12]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+12],xmm1
movss xmm2,德沃德PTR[eax+16]
cvtps2pd xmm2,xmm2
cvtps2pd xmm1,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+16],xmm1
movss xmm1,DWORD PTR[eax+20]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+20],xmm1
movss xmm1,DWORD PTR[eax+24]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+24],xmm1
movss xmm1,DWORD PTR[eax+28]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+28],xmm1
movss xmm1,DWORD PTR[eax+32]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+32],xmm1
movss xmm1,DWORD PTR[eax+36]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+36],xmm1
movss xmm2,德沃德PTR[eax+40]
cvtps2pd xmm2,xmm2
cvtps2pd xmm1,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+40],xmm1
movss xmm1,DWORD PTR[eax+44]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+44],xmm1
movss xmm2,德沃德PTR[eax+48]
cvtps2pd xmm1,xmm0
cvtps2pd xmm2,xmm2
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+48],xmm1
movss xmm1,DWORD PTR[eax+52]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
movss DWORD PTR[eax+52],xmm1
movss xmm1,DWORD PTR[eax+56]
cvtps2pd xmm1,xmm1
cvtps2pd xmm2,xmm0
mulsd xmm1,xmm2
cvtpd2ps xmm1,xmm1
cvtps2pd xmm0,xmm0
movss DWORD PTR[eax+56],xmm1
movss xmm1,DWORD PTR[eax+60]
cvtps2pd xmm1,xmm1
mulsd xmm1,xmm0
流行电子数据交换
cvtpd2ps xmm0,xmm1
movss DWORD PTR[eax+60],xmm0
波普esi
返回;
ret 0
mul1 ENDP
将其与VS 2015生成的
mul1
代码进行比较:

mul1程序
_m$=8;大小=64
$ReturnUdt$=ecx
f$=xmm2s
;WMatrix out=m;
movups xmm0,XMMWORD PTR_m$[esp-4]
;for(无符号整数i=0;i<4;i++)
异或eax,eax
movaps xmm1,xmm2
movups XMMWORD PTR[ecx],xmm0
movups xmm0,XMMWORD PTR_m$[esp+12]
shufps xmm1,xmm1,0
movups XMMWORD PTR[ecx+16],xmm0
movups xmm0,XMMWORD PTR _m$[esp+28]
movups XMMWORD PTR[ecx+32],xmm0
movups xmm0,XMMWORD PTR _m$[esp+44]
movups XMMWORD PTR[ecx+48],xmm0
新议程4
$LL4@mul1:
;for(无符号整数j=0;j<4;j++)
; {
;unsigned int idx=i*4+j;//关键代码
;*(&out._11+idx)*=f;//关键代码
movups xmm0,XMMWORD PTR[ecx+eax*4]
mulps xmm0,xmm1
movups XMMWORD PTR[ecx+eax*4],xmm0
埃克斯公司
cmp eax,4
简体字$LL4@mul1
返回;
mov-eax,ecx
ret 0
?mul1@@YA?AUWMatrix@@U1@M@Z ENDP;mul1
_文本结尾
是伊米
1.000, 2.000, 3.000, 4.000
5.000, 6.000, 7.000, 8.000
9.000, 10.000, 11.000, 12.000
13.000, 14.000, 15.000, 16.000

0.500, 1.000, 1.500, 2.000
2.500, 3.000, 3.500, 4.000
4.500, 5.000, 5.500, 6.000
6.500, 7.000, 7.500, 8.000

0.500, 1.000, 1.500, 2.000
2.500, 3.000, 3.500, 4.000
4.500, 5.000, 5.500, 6.000
6.500, 7.000, 7.500, 8.000
movss   xmm1, DWORD PTR _f$[esp-4] ; load xmm1 from _11 of source
; ...

shufps  xmm1, xmm1, 0               ; duplicate _11 across floats of xmm1
; ...

for ecx = 0 to 3 {
    movups  xmm0, XMMWORD PTR [dest+ecx*4] ; load 4 floats from dest
    mulps   xmm0, xmm1                     ; multiply each by _11
    movups  XMMWORD PTR [dest+ecx*4], xmm0 ; store result back to dest
}