原文: https://mohitmv.github.io/blog/Shocking-Undefined-Behaviour-In-Action/
看到一篇 C++ 未定义行为的简单例子分享一下
简单的有限循环变成无穷循环
1. #include <iostream>
2.
3. int main() {
4. char buf[50] = "y";
5. for (int j = 0; j < 9; ++j) {
6. std::cout << (j * 0x20000001) << std::endl;
7. if (buf[0] == 'x') break;
8. }
9. }
编译器: GCC 11.1.0
编译选项: -Wall -Wextra -std=c++17 -pedantic-errors
https://wandbox.org/permlink/h1zB3mYSD3pCHiIV
使用以上编译选项程式印出 9 次数字后就会正常结束
但是最佳化(-O2 或是 -O3)后执行会变成无穷循环
这是因为段程式码有未定义行为(signed integer overflow)
由于编译器在最佳化时可以假设 signed integer overflow 不会发生
编译器会先将程式码转换为
1. for (int p = 0; p < 9 * 0x20000001; p += 0x20000001) {
2. std::cout << p << std::endl;
3. if (buf[0] == 'x') break;
4. }
接着把" p < 9 * 0x20000001 " 简化为 true
因为 4,831,838,217 (9*0x20000001) 比 p 可能的最大值 INT_MAX 还大
所以结果永远为 true
程式码因此变成
1. for (int p = 0; true; p+=0x20000001) {
2. std::cout << p << std::endl;
3. if (buf[0] == 'x') break;
4. }
而形成无穷循环