[閒聊] 令人驚訝的未定義行為例子
看板C_and_CPP (C/C++)作者nh60211as (xXx_5354M3_31M0_xXx)時間2年前 (2022/04/26 11:33)推噓9(9推 0噓 19→)留言28則, 13人參與討論串1/1
原文: 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. }
而形成無窮迴圈
--
https://i.imgur.com/kCK9K0T.jpg
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 125.228.71.204 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1650944021.A.3AA.html
→
04/26 12:31,
2年前
, 1F
04/26 12:31, 1F
推
04/26 14:55,
2年前
, 2F
04/26 14:55, 2F
推
04/27 00:54,
2年前
, 3F
04/27 00:54, 3F
推
04/28 08:13,
2年前
, 4F
04/28 08:13, 4F
推
04/28 10:01,
2年前
, 5F
04/28 10:01, 5F
→
04/28 10:33,
2年前
, 6F
04/28 10:33, 6F
→
04/28 10:34,
2年前
, 7F
04/28 10:34, 7F
→
04/28 10:34,
2年前
, 8F
04/28 10:34, 8F
→
04/28 10:42,
2年前
, 9F
04/28 10:42, 9F
→
04/28 10:44,
2年前
, 10F
04/28 10:44, 10F
→
04/28 10:44,
2年前
, 11F
04/28 10:44, 11F
→
04/28 19:51,
2年前
, 12F
04/28 19:51, 12F
→
04/29 08:29,
2年前
, 13F
04/29 08:29, 13F
→
04/29 08:30,
2年前
, 14F
04/29 08:30, 14F
→
04/29 08:32,
2年前
, 15F
04/29 08:32, 15F
→
04/29 08:32,
2年前
, 16F
04/29 08:32, 16F
→
04/29 08:33,
2年前
, 17F
04/29 08:33, 17F
推
05/03 15:50, , 18F
05/03 15:50, 18F
→
05/03 15:50, , 19F
05/03 15:50, 19F
→
05/03 15:52, , 20F
05/03 15:52, 20F
→
05/03 15:52, , 21F
05/03 15:52, 21F
推
05/08 20:01, , 22F
05/08 20:01, 22F
推
05/15 20:31, , 23F
05/15 20:31, 23F
→
05/15 20:31, , 24F
05/15 20:31, 24F
推
05/25 10:55, , 25F
05/25 10:55, 25F
推
05/25 18:18, , 26F
05/25 18:18, 26F
→
05/25 18:19, , 27F
05/25 18:19, 27F
→
05/25 18:19, , 28F
05/25 18:19, 28F
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章