专栏中心

EEPW首页 > 专栏 > 一次编译器优化的陷阱

一次编译器优化的陷阱

发布人:天翼云开发者 时间:2025-11-26 来源:工程师 发布文章

本文分享自天翼云开发者社区《一次编译器优化的陷阱》.作者:郑****颖

某次问题排查,最终隐掉完所有业务逻辑后, 化简为如下的简单代码:

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

#include <time.h> #include <stdio.h> #include <stdlib.h> #include <cstring> #include <string.h> #include <unistd.h> 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最高位为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的判断优化掉,导致优化后的代码

逻辑不符合预期。


专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们

关键词: CDN

相关推荐

看完这个,还觉得IPV6离你很远吗?

网络与存储 2020-06-29

终于发了!工信部发放首批CDN牌照 CDN市场准入门槛提高

从Gartner最新全球报告看云CDN服务商的崛起之路

微软建立全球专属CDN网络:平均延迟50ms

网络与存储 2018-05-09

智能路由发展“青黄不接” 优酷有何良策?

消费电子 2016-06-13

Akamai: 全球连网速度持续提升

工信部:获得CDN牌照的企业达到70家

CDN网络路由技术

资源下载 2010-04-24

CDN网络加速与SSL加速

网络与存储 2022-10-28

CDN市场一片繁华 只待标准化

2017-04-14

云服务市场,小厂商的出路在哪儿?

智能计算 2018-05-04

电磁兼容性测试规范

资源下载 2008-09-23

电磁兼容标准修订

更多 培训课堂
更多 焦点
更多 视频

技术专区