Chinaunix首页 | 论坛 | 博客
  • 博客访问: 539427
  • 博文数量: 906
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7350
  • 用 户 组: 普通用户
  • 注册时间: 2022-03-07 15:28
个人简介

天翼云是中国电信倾力打造的云服务品牌,致力于成为领先的云计算服务提供商。提供云主机、CDN、云电脑、大数据及AI等全线产品和场景化解决方案。

文章分类

全部博文(906)

文章存档

2026年(11)

2025年(202)

2024年(244)

2023年(247)

2022年(202)

我的朋友

分类: 网络与安全

2025-11-26 11:54:13

本文分享自天翼云开发者社区《一次编译器优化的陷阱》.作者:郑****
某次问题排查,{BANNED}{BANNED}最佳佳终隐掉完所有业务逻辑后, 化简为如下的简单代码:

来看一下,这个的bcount is zero 会打印吗?
#include

#include

#include

#include

#include

#include

 

int

main(void)

{

  int bcount = 2;

 

  while (bcount < 1296005092) {

     if (bcount < 1296005092) {

       printf("b %lld (%d)%x is <  than %lld\n",bcount,bcount, bcount,1296005092);

     } else {

       printf("b %lld (%d)%x is >= than %lld\n",bcount,bcount,bcount, 1296005092);

     }

     sleep(1);

 

     if (bcount == 0) {

      printf("bcount is zero\r\n");

       return -1;

     }

     bcount *= 2;

  }

 

  return 0;

}

 这个demo代码的逻辑为:

while循环中比较bcount与1296005092的大小,当bcount >=1296005092或者 bcount为0,结束循环。

使用gcc  -O2优化编译后,查看demo程序的输出如下,可以看到,会导致一直在while死循环, 原因是bcount为int 。 然后待比较的那个数 刚好卡

在一个区间,具体如下:当bcount ==0x80000000时候,bcount{BANNED}{BANNED}最佳佳高位为1, 这样该数为负数,小于待比较的数1296005092,注意:

上一次循环中,由于上一个值0x40000000的时候刚好比1296005092小,然后此次循环结果为负数,而下一个循环这个int溢出结果为0 ,所以一直

卡在这里。那么问题就变成了:其中的bcount==0 不会生效??


使用-O1编译后,查看demo代码的输出如下, 可以看到while循环中可以判断到bcount为0.


结论

简化代码,对比两者汇编代码的区别如下,

可以看到在gcc的O2优化等级上,如果是乘2运算,优化后的代码认为结果不应该为0。

到此为止,这里如果将代码中的bcount乘2运算,替换为左移一位,在O2模式下编译,while循环也可以正常退出。

这里应该是gcc的O2等级以上优化逻辑有bug,在整数乘法运算下,编译器认为不可能出现结果为0,将代码中与0的判断优化掉,导致优化后的代码

逻辑不符合预期。

 
 


阅读(5) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~