Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.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++ 这是一个gcc-O2优化错误(与-O1的结果不同)?_C++_C_Gcc_Optimization - Fatal编程技术网

C++ 这是一个gcc-O2优化错误(与-O1的结果不同)?

C++ 这是一个gcc-O2优化错误(与-O1的结果不同)?,c++,c,gcc,optimization,C++,C,Gcc,Optimization,我写了一个非常简单的程序,它在没有O2的情况下运行正常: $ gcc -O2 error.c -o error $ ./error -6169930235904.000000 0.000000 -6169804406784.000000 0.000000 #包括 #包括 int main() { uint32_t A[4]={1,2,3,4}; 浮点B[4]={0,0,0,0}; 浮点数C[4]={5,6,7,8}; int i; //将整数A转换为浮点B 对于(i=0;i

我写了一个非常简单的程序,它在没有O2的情况下运行正常:

$ gcc -O2 error.c -o error
$ ./error
-6169930235904.000000
0.000000
-6169804406784.000000
0.000000
#包括
#包括
int main()
{
uint32_t A[4]={1,2,3,4};
浮点B[4]={0,0,0,0};
浮点数C[4]={5,6,7,8};
int i;
//将整数A转换为浮点B
对于(i=0;i<4;i++)
B[i]=(浮动)A[i];
//从B到C的内存拷贝
uint32_t*src=(uint32_t*)(B);
uint32_t*dst=(uint32_t*)(C);
dst[0]=src[0];
dst[1]=src[1];
dst[2]=src[2];
dst[3]=src[3];
#如果0
//打开此项以更正错误
__asm_uuu(“:”内存”);
#恩迪夫
//打印C,C应该是[1.0,2.0,3.0,4.0]
对于(i=0;i<4;i++)
printf(“%f\n”,C[i]);
返回0;
}
编译时不使用
-O2

$ gcc -O2 error.c -o error
$ ./error
-6169930235904.000000
0.000000
-6169804406784.000000
0.000000
$gcc错误.c-o错误
美元/错误
1
2
3
4
它按预期工作。但是如果我添加了一个
-O2

$ gcc -O2 error.c -o error
$ ./error
-6169930235904.000000
0.000000
-6169804406784.000000
0.000000
此外,如果您将
#如果0
切换到
#如果1
,它将再次正常工作。
asm(“:“内存”)
在同一线程中应该是不必要的

这是一个
-O2
优化的错误吗


有什么事我可以告诉编译器去处理吗??我有一个将xmm寄存器存储到(void*)指针的函数,如:

inlinevoid存储寄存器(void*ptr,const\uu m128®)
{
#如果你没有
const uint32\u t*src=重新解释铸件(®);
uint32_t*dst=重新解释铸件(ptr);
dst[0]=src[0];
dst[1]=src[1];
dst[2]=src[2];
dst[3]=src[3];
#否则
_mm_storeu_si128(重新解释铸造(ptr),_mm_castps_si128(注册));
#恩迪夫
}

dst
是上面代码中的
C
,可以在不修改函数签名的情况下使其正确。

不,这不是编译器错误的表现

相反,由于您使用了强制转换的结果,代码的行为是未定义的。这违反了严格的别名


编译器——特别是gcc——在处理未定义的结构时变得越来越激进。标准允许它们假设未定义的行为不会发生,并且可以删除包含它的任何分支。

看起来像是由于严格的别名冲突而导致的未定义的行为
uint32_t*src=(uint32_t*)(B);uint32_t*dst=(uint32_t*)(C)打破了严格的别名规则。一般经验法则:如果您看到“优化bug”,很可能是代码中未定义的行为。使用
std::copy
(C++)或
std:
memcpy
(C/C++)。
gcc-Q-v-O2 main.cpp
详细显示gcc使用的优化标志。注意:并非所有
-O2
下的优化都有相应的单独标志。和<>代码-O0禁用除C标准或C++标准之外的所有优化。(因为代码有未定义的行为而禁用优化只是一个创可贴,而不是好的编程实践。)我能告诉编译器注意什么吗?我有一个函数将xmm寄存器存储到一个(void*)指针,这是我的问题中的B。@skywind3000
std::copy
,救命!或者<代码> MeMcPy< /C>,尽管C++标签看起来是C代码。