看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: Win10, Linux, ...) Win10 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) GCC 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) 問題(Question): 遇到題目問這題的輸出,我的想法是先將x=x-1 後續就不太知道該怎麼判斷,而且用兩個ide跑出的結果不同 int main() { int A[3] = {0, 0, 0}; int x = 1; A[x++] = --x; printf("A[0]=%d, A[1]=%d, A[2]=%d", A[0], A[1], A[2]); } 餵入的資料(Input):預期的正確結果(Expected Output): 用code block跑出來是 A[0]=1, A[1]=0, A[2]=0 https://i.imgur.com/3UGzFqf.jpg
用線上ide codechef跑出來是 A[0]=0, A[1]=1, A[2]=0 https://i.imgur.com/oYd3YFB.jpg
錯誤結果(Wrong Output): 程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔) 已於上述列出 麻煩各位大大 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.136.255.127 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1630382935.A.E4F.html
peterbrucele: 這是undefined behavior 請參考sequence point08/31 12:12
LPH66: 置底十三誡之八08/31 12:39
wawi2: 聽說現在2021年 希望2031不要再有這種問題 雖然這問題我20008/31 14:02
wawi2: 1就見過08/31 14:02
題目不是我出的啊大哥,遇到我也很困擾,不知道怎麼解
b0920075: 同學去面大M 題目還是有同個 expression 多次對同樣變08/31 14:24
b0920075: 數加減08/31 14:24
這種真的是各種考試很愛考
MartinJ40: 這C++17有規範不是嗎?08/31 14:51
※ 編輯: CaliforCat (114.136.255.127 臺灣), 08/31/2021 16:33:27
d630200x: 垃圾題,但我想台灣2041還會繼續出這種題目 08/31 18:09
a27417332: 謝謝樓上M大提點,翻了規格跟置底以後才發現QQ 08/31 20:31
pponywong: 這種看不出功力的白癡題一堆人很愛考 09/02 12:47
pponywong: 還有operator precedence 也是 是來寫軟體還是來 09/02 12:47
pponywong: 被課本的阿 09/02 12:48
pponywong: 怎麼要考這種 怎麼不叫面試者把linux kernel默寫下來 09/02 12:48
MOONRAKER: 更,以前某公司筆試不是考op precedence 是考整題 09/02 14:40
MOONRAKER: expr evaluation 09/02 14:40
MOONRAKER: 那公司裡面暗暗的 感覺會發霉 09/02 14:41
MOONRAKER: 喔對 不是只考一題 是考一堆的最後一題expr evaluation 09/02 14:42
MasterChang: 不該寫出這種code的題目實在不該出.... 09/03 01:03
ck574b027: 一模一樣耶,484有人以為用置底出題就叫考試 09/03 04:50
xiao2chen: 考這個真的很無聊 09/03 12:56
xiao2chen: 進公司狂寫這種code 看看主管爽不爽 09/03 12:57
sarafciel: 要考也應該是考這種code爛在哪邊XD 09/03 13:43
sarafciel: C++17雖然有定序了 但我記得C的standard還沒定吧? 09/03 13:45
sarafciel: 而且不管有沒有定 都不會改變這個寫法就是爛的事實 09/03 13:46
cuteSquirrel: 鳥題目+1 實務上code review不會過 09/05 17:32
Lipraxde: 那不好說XD 09/06 00:07
sunev: 如果是C++17, 這題答案是? 09/06 11:18
pionlang5566: 應該查記錄看這行垃圾是誰寫的 然後拿棒球棍揍他 09/07 06:34
cuteSquirrel: 結果發現是經理 XDDDDD 09/07 11:48
HMKRL: 就算有定義還是爛寫法啊 直接衝擊可讀性 09/08 02:32
loveme00835: 那就要看看樓上說的「可讀性」用的是什麼指標了 09/08 17:16
loveme00835: 一般常用的 McCabe's CC (Cyclomatic Complexity) 在 09/08 17:23
loveme00835: 分行寫或併在一起都不會影響複雜度. 那會衝擊可讀性 09/08 17:23
loveme00835: 的點是? 09/08 17:23
pponywong: 樓上可讀性跟複雜度無關阿 變數名稱取aaabb123232cc 09/09 07:33
pponywong: 函式名稱取djsadoi_jasdj_jasdjadiasd__dasd() 09/09 07:33
pponywong: 複雜度沒變 所以你很容易讀嗎? 09/09 07:34
loveme00835: 數值計算和命名風格有什麼關係? 09/09 08:10
pponywong: 沒關係啊? 所以哩? 你想表達什麼? 不影響複雜度所以 09/09 08:23
pponywong: 跟可讀性無關? 09/09 08:23
pponywong: 你的可讀性是人讀還是編譯器讀? 09/09 08:24
pponywong: 就算是編譯器讀 你函式長度也會影響編譯器front end 09/09 08:27
pponywong: lookup token的時間阿 09/09 08:27
pponywong: 所以哪來沒影響 09/09 08:28
loveme00835: 我想你可能把 readability 還有 understandability 09/09 12:19
loveme00835: 搞混了, 前者只關心語法, 後者在乎的還有語意. 如果 09/09 12:19
loveme00835: 你講到認知負擔 (cognitive load) 那還多少有點關係, 09/09 12:21
loveme00835: 但如果把 LOC (Line of Code) 增加, 確定真的會減輕 09/09 12:22
loveme00835: 認知負擔嗎? 這就像你說寫 raw loop 找陣列最大值, 09/09 12:23
loveme00835: 而不是用 max_element(), 哪種比較好? 還是說只要有 09/09 12:24
loveme00835: 程式碼看不懂, 先說它爛, 可讀性差就贏了? 09/09 12:24
pponywong: ... whatever 你的定義隨便一說 09/09 13:26
loveme00835: 這不是我自己隨便定義的, ISO 2502n 就有相關的描述, 09/09 15:13
loveme00835: 在我看來這篇文章問的程式碼問題並沒有很大, 可是卻 09/09 15:13
loveme00835: 被罵到臭頭; 但是更嚴重的如: int i = 1 << 16; 可能 09/09 15:14
loveme00835: 大家都寫到無感. 從 security 觀點來看還蠻耐人尋味 09/09 15:15
loveme00835: 問題沒有很大的點在於: 即使把評估順序調換, 也不會 09/09 15:21
loveme00835: 發生存取違規, 因此差別只在讀者對語言的熟悉程度 09/09 15:23
ck574b027: 就繼續滑坡啊,以函數替換相同功能程式跟濫用postfix 09/09 17:20
ck574b027: 是同等級嗎。大家也能照樣造句:如果減少LOC,真的不 09/09 17:20
ck574b027: 會增加認知負擔嗎?啊不就幹話。感謝示範,只要幹話 09/09 17:20
ck574b027: 接滑坡,人人都可以是辯論大師 09/09 17:20
HMKRL: 不會違規存取但會不會造成不符預期的行為?然後i = 1 << 16 09/10 01:33
HMKRL: 跟這個你覺得能一眼看懂的人哪邊比較多 09/10 01:33
protoss: 這就很像以前人家推薦聖經本說過的...寧願一本厚厚的書慢 09/10 02:05
protoss: 慢翻都沒疑問...也不要一本薄薄的越看問題越多... 09/10 02:05
loveme00835: to HMKRL: 你看懂了 i = 1 << 16, 那有看出不預期行 09/10 10:17
loveme00835: 為嗎? 它同時有對 bit-pattern, padding, 還有 sizeo 09/10 10:17
loveme00835: f(int) 的假設. 但是它好寫好讀 09/10 10:17
loveme00835: 無論是 undefined, implementation-defined, 撰寫時 09/10 10:21
loveme00835: 當然都需要注意, 才能寫出可攜的程式碼. 但有些很直 09/10 10:22
loveme00835: 覺的程式碼, 是因為我們強加了很多假設才顯得直覺, 09/10 10:23
loveme00835: 程式碼早已經不可攜, 這種情況下才去找那些顯而易見 09/10 10:23
loveme00835: 的 UB 其實幫助不大 09/10 10:24
HMKRL: 我懂你的意思,在跨平台跨環境的狀態下這種寫法當然可能有 09/10 14:23
HMKRL: 問題 但我遇到這類狀況甚至會再寫明確一點(例如使用int32_ 09/10 14:23
HMKRL: t避開int位元數問題) 09/10 14:23
HMKRL: 如果是在同一個大家一起開發的平台環境,我想原文寫法製造 09/10 14:23
HMKRL: 的時間成本絕對大於1<<16 09/10 14:23
loveme00835: 我覺得時間成本因人而異, 就像我舉的例子, 對初學者 09/10 14:57
loveme00835: 而言, 'A' <= c && c <= 'Z' 比較直覺; 但對有經驗 09/10 14:58
loveme00835: 的人來說 isupper() 更直覺. 如果就是在確定的編譯器 09/10 15:00
loveme00835: 版本討論本文的問題, 我覺得它跟 int 位移的問題沒 09/10 15:01
loveme00835: 差多少 09/10 15:02
HoloLens: 按樓上邏輯一堆style guide都寫開心的,沒有甚麼太多是 09/10 23:32
HoloLens: 會影響可讀性的 09/10 23:32
loveme00835: style guide 是給沒辦法把程式碼寫好的人遵守, 用來 09/11 02:04
loveme00835: 確保程式碼品質最簡單, 也是最後的手段 09/11 02:04
steve1012: 每個人習慣跟喜歡的style 都有差 style guide 是為了 09/11 12:44
steve1012: 有一個可以參考的基準 跟會不會寫無關 09/11 12:44
steve1012: 會寫好的人可以有很多種寫法 09/11 12:44
CoNsTaR: L 大的推文不知道為什麼有種這個的既視感 09/11 16:13
CoNsTaR: https://youtu.be/4ZK8Z8hulFg 09/11 16:13
loveme00835: 舉個例子, 為什麼交通工具要等紅綠燈? 為什麼救護車 09/11 18:13
loveme00835: 可以闖紅綠燈? 重點是追求目標 (軟體的可維護性), 而 09/11 18:14
loveme00835: 不是方法 (死背規則). 要讓組織的人都能寫出可理解性 09/11 18:15
loveme00835: 高的程式碼, 可以投入很多訓練, 可以導入自動化工具 09/11 18:16
loveme00835: 去偵測/修復錯誤; 但是維持 coding standard 是最經 09/11 18:17
loveme00835: 濟的方法, 所以才會普遍. 但不遵守它有沒有錯? 這要 09/11 18:18
loveme00835: 看你只是死背還是可以用不同方法來達成相同目標. 就 09/11 18:20
loveme00835: 像這篇推文一樣, 每個都說 UB 很爛不要寫去背十誡. 09/11 18:21
loveme00835: UB 是什麼? UB 有多爛? 不小心寫了該怎麼辦? 是不是 09/11 18:23
loveme00835: 只有用力背才可以達成大家的期望? 09/11 18:24
loveme00835: 看起來只要把 UB 轉個形式就可以繞過背十誡, 那背的 09/11 18:50
loveme00835: 效益是? 可以量化它嗎? 09/11 18:50
CoNsTaR: 說實話你在這邊 roast 版友和版友 grill UB 考題之間的差 09/12 04:29
CoNsTaR: 異也不是很大... 09/12 04:29
CoNsTaR: 然後忍不住吐槽一下,版友從頭到尾都在說考這個題目沒有 09/12 04:29
CoNsTaR: 鑑別度/考這個題目實務上沒什麼幫助/考這個很無聊,不知 09/12 04:29
CoNsTaR: 道是怎麼被你上綱成 UB 很爛然後在這邊跟版友吵的? 09/12 04:29
CoNsTaR: 剛剛才看到有一個版友說那是爛寫法,原來你只有在跟他吵 09/12 04:38
CoNsTaR: 誤會了,抱歉 orz 09/12 04:38
CoNsTaR: 但並沒有像你講的"這篇推文每個都說 UB"很爛,大家只是 g 09/12 04:43
CoNsTaR: et tired of 這種考題了而已 09/12 04:43
CoNsTaR: 而且我很懷疑像你講的情況你自己都相不相信,事實就是沒 09/12 04:52
CoNsTaR: 有人會因為在意這種寫法也是有可行的時候的事實而不想完 09/12 04:52
CoNsTaR: 全不用它,我想大部分人都遇不到 absolutely need 這種寫 09/12 04:52
CoNsTaR: 法的情況(我懷疑任何人會遇到) 09/12 04:52
loveme00835: 事實就是連 i + 1 也會踩到 UB, 所以一定遇到, 只是 09/12 13:45
loveme00835: 看你有沒有意識到, 甚至去避免 UB 帶來的影響. 有些 09/12 13:47
loveme00835: UB 特別被重視的原因只是它們比較容易被觀察到而已 09/12 13:48
loveme00835: 和這題和 coding standard 關聯起來其實有點謎, 首先 09/12 13:50
loveme00835: 得要知道套用 coding standard 對於維護性有什麼幫助 09/12 13:50
loveme00835: , 譬如新人上手的時間 (可理解性), 平均解決 defeat 09/12 13:51
loveme00835: 的時間 (可修改性), 這些指標都要建立起來, 並且和套 09/12 13:51
loveme00835: 用 coding standard 以前相比有改善, 那麼我們才會說 09/12 13:52
loveme00835: coding standarad 對於某公司的某個環境是有幫助的, 09/12 13:52
loveme00835: 不然說"避免 XX 的寫法比較安全"什麼的大部分情況都 09/12 13:54
loveme00835: 是自我感覺良好, 如果在偵錯的時候還是在用逐步執行 09/12 13:55
loveme00835: , 還是免不了加新的 log, 那怎麼寫對你而言都沒差 09/12 13:55
loveme00835: 因為語言的本質, 程式碼裡存在的 UB 只有多跟少的區 09/12 14:29
loveme00835: 別; 並不是有和沒有這樣單純的情形 09/12 14:29
CoNsTaR: 我覺得我可能要再重新幫你畫一次重點: 09/12 22:34
CoNsTaR: 大家在罵的是每次都考這種考了也不知道能幹嘛的題目很煩 09/12 22:34
CoNsTaR: 其實真的不太有人在跟你討論你個人認為的 UB 真理 best p 09/12 22:34
CoNsTaR: ractices 所以,拜託了 09/12 22:34
CoNsTaR: 最後你可能誤解我“那種寫法”的意思了,我指的是 OP 問 09/12 22:34
CoNsTaR: 的那種寫法,不是指 UB in general 09/12 22:34
loveme00835: 難道 UB 還要分"這種" UB 還有"別種" UB 嗎? 這才是 09/12 22:57
loveme00835: 我的重點. UB 都是一樣的, 會覺得"這種"考到煩是開始 09/12 22:57
loveme00835: 有差別待遇, 一份至少有 3 個地方會踩到 UB 的程式碼 09/12 22:57
loveme00835: , 只糾結執行順序的問題我也看不出是什麼操作 09/12 22:57
CoNsTaR: orz 你看不出來的操作很簡單,是這樣的: 09/13 10:58
CoNsTaR: 這些題目 100/100 考的是教授個人以為的 C,不是什麼神奇 09/13 10:58
CoNsTaR: 未來 2050 C++ 抽象機器,而在過去目前甚至是可預見的未 09/13 10:58
CoNsTaR: 來的 C 裡面,這個 expression 100/100 是 UB 09/13 10:58
CoNsTaR: meaning that: 09/13 10:58
CoNsTaR: 1. 對考生來講這題沒有教授要的答案 09/13 10:58
CoNsTaR: (你根本不知道教授以為的答案是哪一種) 09/13 10:58
CoNsTaR: 2. 這題很無聊/沒有鑑別度/考了不知道要幹嘛 09/13 10:58
CoNsTaR: (如版友們的推文不一一列舉) 09/13 10:58
CoNsTaR: 然後讓我們來回答你提出的問題: 09/13 10:58
CoNsTaR: 1. 「難道 UB 還要分這種 UB 和別種 UB 嗎」 09/13 10:58
CoNsTaR: 原來是把上次的坡拿來繼續滑的部分啊,我懂你的邏輯 09/13 10:58
CoNsTaR: a. 因為就連像 i+1 這樣一般的 expr 都可能是 UB 09/13 10:58
CoNsTaR: -> b. 所以什麼 expr 都可能是 UB 09/13 10:58
CoNsTaR: -> c. 所以整份 code 到處都是 UB,無法縮小需要檢查的範 09/13 10:58
CoNsTaR: 圍或是針對某部分 code 找出需要檢查的 UB 種類 09/13 10:58
CoNsTaR: -> d. 所以 UB 就是 UB,沒有分這種 UB 那種 UB 09/13 10:58
CoNsTaR: -> e. 所以不能針對某些特殊(例如100%發生)的 UB 做其 09/13 10:58
CoNsTaR: 他處理,否則就是糾結在某種 UB,而且是對 UB 的差別待遇 09/13 10:58
CoNsTaR: 哇~真是神奇的邏輯呢,如果這不是滑坡什麼才是滑坡呢? 09/13 10:58
pponywong: XD 他會跟你解釋 有一種CPU跟compiler int只有1 bit 09/13 11:05
pponywong: 所以寫c語言 int i=2 就會UB 你要注意 XD 09/13 11:06
pponywong: 真的要這樣搞 你可以用 configure.sh 09/13 11:07
pponywong: 或是用preprocessor做靜態檢查就好了 無限延伸這議題 09/13 11:08
pponywong: 有什麼用 想到以前工作 也有個工程師很鑽牛角尖 09/13 11:09
pponywong: 我寫給他chip i2c的函式庫給他用 他就在質疑 有沒有 09/13 11:10
pponywong: error hanlding 我說我有做i2c error handle了 09/13 11:10
pponywong: 他繼續問 有沒有可能i2c寫成功 chip register 沒改變 09/13 11:11
pponywong: 這有沒有檢查 或是register值寫進去了 示波器量出來 09/13 11:12
pponywong: 沒變 這有沒有做error handing....我當場無言... 09/13 11:12
CoNsTaR: 合理懷疑樓上是在釣 L 大出來指正 int 大小規範 09/13 21:23
Lipraxde: 是在寫火箭發射器膩XD 09/13 21:27
pponywong: 要挑剔UB 原文的例子也太多 講不玩了 09/13 22:23
pponywong: 誰說 int A[3] = {0, 0, 0} 一定會成功? 09/13 22:23
pponywong: 搞不好程式根本沒stack size了 一宣告變數就爆了 09/13 22:24
pponywong: 還有print字串那麼長 萬一機器只有12byte 記憶體怎麼辦 09/13 22:29
iLeyaSin365: 現實誰會這樣寫?XD想知道 09/14 07:18