推 dces4212: 推 10/31 15:33
推 sarafciel: 推 10/31 16:06
推 james732: 推 11/01 15:09
→ loveme00835: 從軟體架構的品質屬性 (Quality Attributes) 來看, 11/01 15:46
→ loveme00835: 如果你改了扣, 卻不知道應該要引入哪些標頭檔, 不會 11/01 15:46
→ loveme00835: 很雷嗎? coding standard 只能告訴你結果, 為了確保 11/01 15:46
→ loveme00835: 這個結果, 其實人員的教育/訓練才是最重要的; 而不是 11/01 15:46
→ loveme00835: 透過工具來把訓練不足的問題掩蓋下來, 這也會衍生其 11/01 15:46
→ loveme00835: 他問題 11/01 15:46
問題不是這樣的,假設你今天刪了幾行 code,裡面有一行用到某個資料結構
像是 struct smartdata 好了,而且這是最後一個用到 smartdata 的地方
理論上,應該要去 include 的地方,把 #include<smartdata.h> 刪掉
問題是有多少人會注意到這件事?就連 code review 都不一定會注意到了
又或者專案把 a.h 拆分成 a1.h a2.h 然後 a.h 裡面 include a1.h/a2.h
其他專案會記得把所有 a.h 換成 a1.h 或 a2.h 嗎?
coding standard 是目標,但無論多少教育/訓練,在實行上就是會有疏失
"因為人就是會犯錯,所以在鉛筆的後面會有橡皮擦"
工具是用來輔助人,抓出人犯錯的地方,而不是說人就不用教育/訓練
※ 編輯: lc85301 (220.134.248.249 臺灣), 11/01/2020 17:16:48
→ firejox: 發現人會疏漏的問題就是CI的工作了 11/01 19:19
→ loveme00835: 找錯誤是 testing 在做的事情 11/01 19:23
→ firejox: @@ 找違反coding standard也算testing喔 11/01 19:29
→ lc85301: 所以說這個工具就是要丟給 CI 去跑的呀 11/01 19:53
→ loveme00835: 我的意思是 iwyu 應該單純作為 testing/diagnostic t 11/01 20:06
→ loveme00835: ool, 就像 clang-tidy等, 但是找出錯誤時應該是由人 11/01 20:06
→ loveme00835: 類來修正, 並且要有明確的回報機制. fix_include 不 11/01 20:06
→ loveme00835: 應該放進開發流程, 因為我們無法從最後的程式碼看出 11/01 20:06
→ loveme00835: 它和人員素質之間的關係 11/01 20:06
→ lc85301: 可以接受 11/01 20:34
→ lc85301: 我的使用結果,iwyu 在解完 include 之後還是會有錯 11/01 20:34
推 CoNsTaR: 程式語言都不要 typecheck 好了,寫 type safe 的程式是 11/01 23:14
→ CoNsTaR: 人類的工作,不該由機器來做,typechecking 是測試在做 11/01 23:14
→ CoNsTaR: 的事 11/01 23:14
→ CoNsTaR: 人員的教育訓練才是最重要的 11/01 23:15
推 descent: 感謝分享 11/02 10:03
→ chuegou: 同意推文 類似變數宣告了沒用會跳warning這樣我比較喜歡 11/02 11:13
推 hsnuconan: 所以過度引入會有什麼副作用嗎? compile過慢嗎? 11/04 10:09
→ Killercat: compile三級跳的慢 因為這是連鎖反應 11/04 11:26
→ Killercat: 另外雖然多半肇因於設計錯誤,但是名稱空間衝突機會也 11/04 11:26
→ Killercat: 會變大,當你用兩個3rd party的.h裡面的include還互相 11/04 11:27
→ Killercat: 衝突的時候你真的會欲哭無淚 要改都沒辦法改 11/04 11:27
推 LPH66: 簡單觀念: #include 是編譯器幫你剪貼標頭檔在引入處 11/04 11:33
→ LPH66: 所以 #include 越多最後編譯時要看的東西就越多 11/04 11:34
→ LPH66: 那編譯過程中編譯器需要記錄搜尋判斷的東西就越多 11/04 11:36
推 ucrxzero: 所有的MACRO 包括include 不是都是展開的概念嗎 11/04 12:48
→ ucrxzero: 跟inline 的差別在於inline是編譯器做的是真的函式 11/04 12:50
→ ucrxzero: 而preprocessing是text的代換而已 11/04 12:50
推 ucrxzero: Preprocessing->編譯->處理inline 11/04 12:53
→ ucrxzero: 補充一下 inline 有自己的scope 較穩定 11/04 12:58
→ MOONRAKER: 阿展開以後compiler不用看過喔 那這個compiler太妙了 11/05 16:04
→ MOONRAKER: 不用看就可以變出來bin 妙不可言 11/05 16:04
推 ucrxzero: 當然要看我又沒有說不用看 11/05 16:46
推 ucrxzero: 但不穩定是因為還要加類似do{}while(0)這種東西 11/05 16:51
→ ucrxzero: *MACRO 11/05 16:52
→ Lipraxde: 我在思考這裡是怎麼談到 inline 的... 11/05 18:55
→ eye5002003: GCC能幫我列出沒被使用的函式,也許以後還能幫忙抓沒 11/06 09:07
→ eye5002003: 被使用的標頭檔,不過如果你很在乎編譯時間長短的話 11/06 09:09
→ eye5002003: 那還是要親手整理,把標頭檔藏好別到處引用 11/06 09:11
推 ucrxzero: 像static 就不會被剪貼進去啊 11/06 10:13
→ loveme00835: 笑死.. 11/06 10:19
推 ucrxzero: ... 11/06 10:37
→ firejox: inline 只是 inline it if you can ,又沒強制 11/06 12:41
→ firejox: 如果 static不會剪貼,那 static inline 又是什麼 11/06 12:51
推 CoNsTaR: include 不就單純的剪貼嗎?還會管你是不是 static 喔? 11/06 12:51
→ CoNsTaR: 語法分析可能都還沒開始,不可能管到語意去吧... 11/06 12:53
推 ucrxzero: 好喔最初應該會啦 但你也用不了 11/06 13:01
→ ucrxzero: 喔喔我懂你意思了 11/06 13:02
→ ucrxzero: 我是說在其他source檔定義static同名一起include heade 11/06 13:03
→ ucrxzero: r的其他source抓不到那個被定義static的symbol 11/06 13:03
→ ucrxzero: 但如果你一開始就把static function 寫在header那當然 11/06 13:04
→ ucrxzero: 都可以用 但是你每個source 檔自己定義都是分開的 11/06 13:04
→ ucrxzero: 這樣沒錯吧? 11/06 13:05
推 ucrxzero: text剪貼當然是預處理而已 11/06 13:11
推 CoNsTaR: 呃... 不論某個 symbol 是不是 static、或它被從哪裡 inc 11/06 13:15
→ CoNsTaR: lude 到哪裡、或 scope 是什麼 etc...,它被 include 進 11/06 13:15
→ CoNsTaR: 來就是會增加編譯器的工作,就可能會導致編譯速度變慢, 11/06 13:15
→ CoNsTaR: 就這樣而已... 11/06 13:15
推 ucrxzero: 我用詞錯誤啦 我講到編譯的地方去了 11/06 13:20
→ ucrxzero: 不要再鞭了 11/06 13:20
→ ucrxzero: 更正 講到連結的地方去了 11/06 13:21
→ loveme00835: 就跟你說從結果論來學習是錯的方法, 買一本書好好把 11/06 13:22
→ loveme00835: 它看完, 沒看完別來誤導其他人 11/06 13:22
推 CoNsTaR: 沒有要鞭,看了就忍不住想講 11/06 13:24
→ CoNsTaR: orz 11/06 13:24
推 ucrxzero: 沒錯,這裡傳道授業的地方講話不能太籠統可能會讓人搞 11/06 13:28
→ ucrxzero: 混 我剛剛剪貼是講最後的連結的地方不會被連結 11/06 13:28
→ ucrxzero: 而不是引用的時候不會被剪貼 11/06 13:28
→ ucrxzero: 我略過太多而且用詞不精 11/06 13:29
推 ucrxzero: 大家我先去看書明年見 11/06 15:00
推 ucrxzero: 看講話的藝術 11/06 16:20
→ descent: ucrxzero: 討論就是這樣, 不用太在意 11/06 18:06
→ Killercat: 我能給的建議是,不要急著發表意見 11/10 07:42
→ Killercat: 先把想說的在腦袋裡面順一次 想想要不要發表 再寫 11/10 07:42
→ Killercat: 不過這篇居然沒有人把pImpl拖出來 真令人意外XD 11/10 07:43
推 LPH66: (離題) 這其實是推文成章的壞處之一: 發完出去了就沒得改 11/10 08:30
→ LPH66: (再拉回來) 這麼一提我才發現 pImpl 好像和這段 guide 之間 11/10 08:33
→ LPH66: 有些微妙的互動... 11/10 08:33
→ Lipraxde: Pimpl 在 header 應該沒有用到 impl class 底下的 symb 11/10 08:53
→ Lipraxde: ol,應該還好? 11/10 08:53
→ Killercat: 基本上這條guide就是給沒用pimpl的code補救的方案之一 11/10 14:51
→ Killercat: 你真的寫成pimpl 這東西應該沒辦法再優化了.... 11/10 14:52
→ Killercat: 就全部被凝縮成一個opaque pointer是還能怎麼最佳化XD 11/10 14:53
→ Killercat: 應該說 還是能拿掉用不到的header啦 但效果不明顯了 11/10 14:53
→ Lipraxde: 我是覺得 pimpl 和這條 guide 兩者是獨立的 11/10 20:16
→ Killercat: 是沒錯,不過要是使用pimpl的話,絕大多數的redundent 11/10 22:39
→ Killercat: header都會在.cpp而不在.h 這條guide最佳化就很有限了 11/10 22:39
→ Lipraxde: 這條 guide 應該是要人們避免 transitive include,讓 11/10 23:42
→ Lipraxde: 人可以安心的拿掉不用的 header。編譯速度有機會變快應 11/10 23:42
→ Lipraxde: 該算是屬於附加的,並不是本來的目的。 11/10 23:42
→ Lipraxde: 而使用 pimpl 的其中一個目的是可以讓人修改 impl 時不 11/10 23:42
→ Lipraxde: 用改到 header,可以避免重新編譯其他 .cpp。 11/10 23:42
→ Lipraxde: 就這樣我覺得 pimpl 跟這條 guide 不衝突也不相關。 11/10 23:42
推 mickey94378: 推分享 12/07 20:54