问题
skynet最近有一个issue cluster中session溢出问题,用简单代码模拟一下:(以下代码运行在:gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
)
gcc -O 后,输出:
2147483643
2147483644
2147483645
2147483646
2147483647
gcc -O2 后,死循环:
2147483643
2147483644
2147483645
2147483646
2147483647
-2147483648
-2147483647
-2147483646
-2147483645
-2147483644
.....
为什么开启O2
优化后,程序死循环了?看一下汇编代码
对比可以看出,O2的情况下,编译器优化掉了int32_t
上溢检查的代码,所以出现了死循环。(这个问题在MSVC
和Clang
下不存在)
解决
针对这个问题,反馈问题的同学建议使用volatile
限定符,这种方案可以避免此类优化,但用在这儿并不合适。
volatile限定符告知计算机,代理(而不是变量所在的程序)可以改变该变量的值。通常它被用于硬件地址以及在其他程序或同时运行的线程中共享数据。
– C Primer Plus(第六版) 12.5.2
一种合理的方案是将其转化为更高精度的数值(uint32_t
或int64_t
), 做int32_t
上限的检查。
本文链接, 未经许可,禁止转载