Re: [討論] 對於同事的coding style感到很感冒

看板C_and_CPP (C/C++)作者 (JOMI)時間4年前 (2020/05/13 16:10), 4年前編輯推噓2(2047)
留言49則, 5人參與, 4年前最新討論串3/5 (看更多)
謝謝各位的意見 我會在逐一理解 目前有幾個問題 最近比較被要求寫exceptional 的code 假設我寫 string Foo(string s) noexcept { auto a = Get(); // noexcept string r = s+a; return r; } 然後我確認operator+是不是noexcept 結果當然不是 變成我要為了這簡單的+ 寫一個try catch...去handle exception 三個抉擇點 1. 不要標註noexcept , 反正壞了上面該處理 無責聲明 (我prefer這) 2. try catch(type1) catch(type2) catch(...) 把所有查的到的exception都handle 要不要分開handle 是by design 3. 就現在這樣寫 反正真的發生bad_alloc 我也無能為力 terminate吧 以上有沒有什麼比較建議的做法可以討用在多數情形 現在變成想提供noexcept 函數 都要查每一行function call是否都是noexcept 反而覺得 預設不該noexcept 才合理 有需求才標註noexcept ================== 一個很無聊的const問題 古早的effective c++推廣 能加const就加 所以這位同事當然遵守 void Foo(const int a) { auto const rc = Win32(); auto const hr = COM(); auto const error = 3rdAPI(); ... } 我認同const能確保不被亂改 但我其實是覺得很多餘 local變數改了也不會怎樣(也不該怎樣) 甚至會被改表示你有需求 搞不好還會因此改code拿掉const 問題來了 他今天看到某同事 void Bar(const string s){// read-only } 留言 這是多餘的 要拿掉 對我來說當然不該補const 裡面如果以後有copy需求 就不能move了 但我反倒覺得他兩套標準 這case只有read加上const不正是他遵守的鐵則嗎? 也可以Bar(RVALUE); 為啥這情況他認為"useless"? 雙重標準的感覺 我沒看到他針對函數local non-trivial變數的寫法 也許也是不加const為主 (也是雙標) 這邊的問題就是 盡可能const 這件事如果套用在modern C++ 有沒有什麼common的標準用法呢? 我比較主觀的歸納是 primitive type能const就const non-trivial type 都不要加(但這太偏頗了) 我自己是習慣都不加 以上 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.192.134.52 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1589357431.A.89A.html ※ 編輯: lovejomi (123.192.134.52 臺灣), 05/13/2020 16:22:23

05/13 17:07, 4年前 , 1F
const 不是為了避免修改, 而是要求物件的行為 consistent
05/13 17:07, 1F

05/13 17:10, 4年前 , 2F
這是為什麼 mutable 存在的原因, 這可以從兩個角度來看:
05/13 17:10, 2F

05/13 17:14, 4年前 , 3F
1) 給物件的人 2) 收物件的人, 對於收的人來說加上 const
05/13 17:14, 3F

05/13 17:15, 4年前 , 4F
是希望物件的外顯行為能一致, 這是基本假設. 對給的人來說
05/13 17:15, 4F

05/13 17:17, 4年前 , 5F
加上 const 是用來限縮可用介面, 也許是為了避免狀態被改
05/13 17:17, 5F

05/13 17:21, 4年前 , 6F
動, 或者只是想提供不同的介面組合給對方 (使用 ref
05/13 17:21, 6F

05/13 17:23, 4年前 , 7F
qualifier 也可以達成類似目的). 所以收的時候需要注意綁
05/13 17:23, 7F

05/13 17:23, 4年前 , 8F
定的 value category 以及 constness, 給的人也要看情況使
05/13 17:23, 8F

05/13 17:24, 4年前 , 9F
用 std::forward()/std::move()/std::as_const()
05/13 17:24, 9F

05/13 17:30, 4年前 , 10F
所以 pass by value 的情況下不用加上 const 的原因是使
05/13 17:30, 10F

05/13 17:31, 4年前 , 11F
用者只有執行函式的執行緒, 所以要求行為一致是沒有意義的
05/13 17:31, 11F

05/13 17:57, 4年前 , 12F
noexcept 的用意和 throw() 不一樣, 在 C++ 裡我們應該預
05/13 17:57, 12F

05/13 17:58, 4年前 , 13F
設所有函式都會 throw 但你可以透過 throw() 來說你其實不
05/13 17:58, 13F

05/13 17:59, 4年前 , 14F
會 throw, 而編譯器所做的相應處理是把 propagate excepti
05/13 17:59, 14F

05/13 18:00, 4年前 , 15F
on 的 code 拿掉, 換句話說 noexcept 是優化的手段和
05/13 18:00, 15F

05/13 18:01, 4年前 , 16F
exception handling 策略無關, 那取捨其實就看團隊了, 大
05/13 18:01, 16F

05/13 18:01, 4年前 , 17F
部分針對 scalar type 的操作比較容易加上 noexcept 來優
05/13 18:01, 17F

05/13 18:02, 4年前 , 18F
化, 而其他情形就看你們對效能的要求來做決定. 這都是需要
05/13 18:02, 18F

05/13 18:03, 4年前 , 19F
先做 profiling
05/13 18:03, 19F

05/13 18:09, 4年前 , 20F
上面我需要理解一下,如果是primitive 加上const是必要
05/13 18:09, 20F

05/13 18:09, 4年前 , 21F
的嗎?
05/13 18:09, 21F

05/13 18:19, 4年前 , 22F
跟是不是 primitive 無關, 由預期的行為決定加不加 const
05/13 18:19, 22F

05/13 18:20, 4年前 , 23F
如果你期望兩次 std::cout << i << std::endl; 出來的值都
05/13 18:20, 23F

05/13 18:20, 4年前 , 24F
把 propagate exception 的 code 拿掉 <== 我想確認
05/13 18:20, 24F

05/13 18:20, 4年前 , 25F
內部使用try catch(...){} 確保他不會propagate 這件事
05/13 18:20, 25F

05/13 18:20, 4年前 , 26F
應該跟"compiler拿掉" 兩者沒衝突對吧?
05/13 18:20, 26F

05/13 18:20, 4年前 , 27F
要一樣, 不應該有其他執行緒去更改值, 最好加上 const 來
05/13 18:20, 27F

05/13 18:21, 4年前 , 28F
表達意圖
05/13 18:21, 28F

05/13 18:26, 4年前 , 29F
沒錯, 但 noexcept 與否應該藉由實作程式碼來決定而不是反
05/13 18:26, 29F

05/13 18:26, 4年前 , 30F
過來由介面限制實作, 你在裡面寫了 try-catch 其實是和編
05/13 18:26, 30F

05/13 18:27, 4年前 , 31F
譯器做類似的事情, 所以我們才會用 noexcept() 運算子來決
05/13 18:27, 31F

05/13 18:28, 4年前 , 32F
定函式的 signature 而不是用人工去比對
05/13 18:28, 32F

05/13 21:29, 4年前 , 33F
那 class member 要加 const 嗎? 如果初始化之後就不變了
05/13 21:29, 33F

05/13 21:53, 4年前 , 34F
@poyenc: 問一下,你有這樣深入見解是有讀什麼文章或書
05/13 21:53, 34F

05/13 21:53, 4年前 , 35F
籍嗎
05/13 21:53, 35F

05/13 22:01, 4年前 , 36F
我也從網路上找不少文章但沒有這麼深入
05/13 22:01, 36F

05/13 22:02, 4年前 , 37F
另外 以我的範例 你會怎麼抉擇實作 謝謝
05/13 22:02, 37F

05/13 22:05, 4年前 , 38F
@FRAXIS 要看你對該 instance variable 型別有什麼要求,
05/13 22:05, 38F

05/13 22:06, 4年前 , 39F
在介面受限的情況下是不是還能實作你想要的類別, 來去決定
05/13 22:06, 39F

05/13 22:07, 4年前 , 40F
constness, @lovejomi 只是比較常和 committee member 討
05/13 22:07, 40F

05/13 22:08, 4年前 , 41F
論而已, 我覺得要看你對 const 的理解是到語法層還是語意
05/13 22:08, 41F

05/13 22:10, 4年前 , 42F
層, 我的習慣是預設全加 const, 還有需要 noexcept 的情況
05/13 22:10, 42F

05/13 22:11, 4年前 , 43F
全用 noexcept(bool) 來決定. 預設全加 const 是為了減輕
05/13 22:11, 43F

05/13 22:12, 4年前 , 44F
讀碼的負擔還有方便驗證, 不過 pass by value 不會加const
05/13 22:12, 44F

05/13 22:13, 4年前 , 45F
因為這情況在介面加 const 是多餘的
05/13 22:13, 45F

05/14 09:05, 4年前 , 46F
至今沒寫過一次noexcept,這東西以後被刪除的機率很高
05/14 09:05, 46F

05/14 09:08, 4年前 , 47F
我常常寫foo(const std::string &str);既然read only
05/14 09:08, 47F

05/14 09:10, 4年前 , 48F
就沒必要整個複製一遍了
05/14 09:10, 48F

05/14 22:38, 4年前 , 49F
如果是string的話直接用string_view吧
05/14 22:38, 49F
文章代碼(AID): #1UkwjtYQ (C_and_CPP)
文章代碼(AID): #1UkwjtYQ (C_and_CPP)