gpt4 book ai didi

c - 这是 gcc -O2 优化错误(与 -O1 的结果不同)吗?

转载 作者:行者123 更新时间:2023-12-02 02:28:07 25 4
gpt4 key购买 nike

我编写了一个非常简单的程序,没有 -O2 时它的行为正常:

#include <stdio.h>
#include <stdint.h>

int main()
{
uint32_t A[4] = { 1, 2, 3, 4 };
float B[4] = { 0, 0, 0, 0 };
float C[4] = { 5, 6, 7, 8 };
int i;

// convert integer A to float B
for (i = 0; i < 4; i++)
B[i] = (float)A[i];

// memory copy from B to 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];

#if 0
// open this to correct the error
__asm__("":::"memory");
#endif

// print C, C should be [1.0, 2.0, 3.0, 4.0]
for (i = 0; i < 4; i++)
printf("%f\n", C[i]);

return 0;
}

不使用-O2进行编译:

$ gcc error.c -o error
$ ./error
1.0000
2.0000
3.0000
4.0000

它按预期工作。但如果我添加了 -O2:

$ gcc -O2 error.c -o error
$ ./error
-6169930235904.000000
0.000000
-6169804406784.000000
0.000000

此外,如果将 #if 0 切换为 #if 1 ,它会再次正常工作。 asm ("":::"memory") 在同一线程中应该是不必要的。

-O2优化的bug吗??

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

inline void StoreRegister(void *ptr, const __m128& reg)
{
#if DONT_HAVE_SSE
const uint32_t *src = reinterpret_cast<const uint32_t*>(&reg);
uint32_t *dst = reinterpret_cast<uint32_t*>(ptr);
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
#else
_mm_storeu_si128(reinterpret_cast<__m128*>(ptr), _mm_castps_si128(reg));
#endif
}

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

最佳答案

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

由于您使用了转换 (uint32_t*)(B) &c 的结果,因此您的代码的行为未定义。这违反了严格别名

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

关于c - 这是 gcc -O2 优化错误(与 -O1 的结果不同)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61370485/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com