gcc-O3,数据指针似乎丢失了

gcc-O3,数据指针似乎丢失了,c,gcc,optimization,C,Gcc,Optimization,根据优化级别,输出不同,如下所示: 具有意外输出: $ gcc -Wall -O3 otest.c -o otest $ otest *x: 0 y: 2048.899902 y: 0.000000 $ gcc -Wall -O2 otest.c -o otest $ otest *x: 45000e6

根据优化级别,输出不同,如下所示:

具有意外输出:

$ gcc -Wall -O3  otest.c -o otest                   
$ otest                                             
*x: 0 
y: 2048.899902 
y: 0.000000 
$ gcc -Wall -O2  otest.c -o otest 
$ otest                           
*x: 45000e66 
y: 0.000000 
y: 2048.899902
预期产出:

$ gcc -Wall -O3  otest.c -o otest                   
$ otest                                             
*x: 0 
y: 2048.899902 
y: 0.000000 
$ gcc -Wall -O2  otest.c -o otest 
$ otest                           
*x: 45000e66 
y: 0.000000 
y: 2048.899902
源代码:

#include <stdio.h>
int main(void)
{
   float y = 2048.9;
   void *p = &y;
   unsigned int *x = p;
   printf(" *x: %x \n",*x);
   *x = 0; 
   printf(" y: %f \n",y);
   *x = 0x45000e66;
   printf(" y: %f \n",y);  
   return 0;
 }
#包括
内部主(空)
{
浮动y=2048.9;
void*p=&y;
无符号整数*x=p;
printf(“*x:%x\n”,*x);
*x=0;
printf(“y:%f\n”,y);
*x=0x45000e66;
printf(“y:%f\n”,y);
返回0;
}
gcc版本为4.2.1


我是否遗漏了任何重要指示?

是的。您的代码违反了严格的别名规则(当您有一个
浮点
,但您通过指向
unsigned int
的指针访问它时,这是一种不兼容的类型),调用了未定义的行为,因此允许编译器对您的代码执行任何它喜欢的操作,包括完全删除它的一部分。

是的。您的代码违反了严格的别名规则(当您有一个
float
,但您通过指向
unsigned int
的指针访问它时,这是一种不兼容的类型),调用了未定义的行为,因此允许编译器对您的代码执行任何它喜欢的操作,包括完全消除它的一部分。

-fn没有严格的别名。
@marglisse甚至不建议这样做。是的,但你的评论表明这是一个解决方案。不是。@ole如果不清楚,评论中的随机词不是“解决方案”或“建议”,而是关于在搜索引擎中键入什么以获取更多信息并了解代码错误的方面的建议。在这种情况下,union更好
-fn没有严格的别名
@Marglisse甚至不建议这样做。是的,但你的评论表明这是一个解决方案。不是。@ole如果不清楚,评论中的随机词不是“解决方案”或“建议”,这是关于如何在搜索引擎中键入内容以获取更多信息并了解代码错误的方面的建议。union在类似这样的别名情况下效果更好。值得指出的是,现在的编译器确实在尝试做正确的事情——他们将在假定可能导致未定义行为的情况下生成代码不存在,这可能会带来很多优化机会…值得指出的是,现在的编译器确实在尝试做正确的事情--他们会在假设导致未定义行为的环境不存在的情况下生成代码,这可能会带来很多优化机会。。。