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

作者: lovejomi (JOMI)   2020-05-13 16:10:29
謝謝各位的意見
我會在逐一理解
目前有幾個問題
最近比較被要求寫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 都不要加(但這太偏頗了)
我自己是習慣都不加
以上
謝謝
作者: poyenc (髮箍)   2020-05-13 17:07:00
const 不是為了避免修改, 而是要求物件的行為 consistent這是為什麼 mutable 存在的原因, 這可以從兩個角度來看:1) 給物件的人 2) 收物件的人, 對於收的人來說加上 const是希望物件的外顯行為能一致, 這是基本假設. 對給的人來說加上 const 是用來限縮可用介面, 也許是為了避免狀態被改動, 或者只是想提供不同的介面組合給對方 (使用 refqualifier 也可以達成類似目的). 所以收的時候需要注意綁定的 value category 以及 constness, 給的人也要看情況使用 std::forward()/std::move()/std::as_const()所以 pass by value 的情況下不用加上 const 的原因是使用者只有執行函式的執行緒, 所以要求行為一致是沒有意義的noexcept 的用意和 throw() 不一樣, 在 C++ 裡我們應該預設所有函式都會 throw 但你可以透過 throw() 來說你其實不會 throw, 而編譯器所做的相應處理是把 propagate exception 的 code 拿掉, 換句話說 noexcept 是優化的手段和exception handling 策略無關, 那取捨其實就看團隊了, 大部分針對 scalar type 的操作比較容易加上 noexcept 來優化, 而其他情形就看你們對效能的要求來做決定. 這都是需要先做 profiling
作者: lovejomi (JOMI)   2020-05-13 18:09:00
上面我需要理解一下,如果是primitive 加上const是必要的嗎?
作者: poyenc (髮箍)   2020-05-13 18:19:00
跟是不是 primitive 無關, 由預期的行為決定加不加 const如果你期望兩次 std::cout << i << std::endl; 出來的值都
作者: lovejomi (JOMI)   2020-05-13 18:20:00
把 propagate exception 的 code 拿掉 <== 我想確認內部使用try catch(...){} 確保他不會propagate 這件事應該跟"compiler拿掉" 兩者沒衝突對吧?
作者: poyenc (髮箍)   2020-05-13 18:20:00
要一樣, 不應該有其他執行緒去更改值, 最好加上 const 來表達意圖沒錯, 但 noexcept 與否應該藉由實作程式碼來決定而不是反過來由介面限制實作, 你在裡面寫了 try-catch 其實是和編譯器做類似的事情, 所以我們才會用 noexcept() 運算子來決定函式的 signature 而不是用人工去比對
作者: FRAXIS (喔喔)   2020-05-13 21:29:00
那 class member 要加 const 嗎? 如果初始化之後就不變了
作者: lovejomi (JOMI)   2020-05-13 21:53:00
@poyenc: 問一下,你有這樣深入見解是有讀什麼文章或書籍嗎我也從網路上找不少文章但沒有這麼深入另外 以我的範例 你會怎麼抉擇實作 謝謝
作者: poyenc (髮箍)   2020-05-13 22:05:00
@FRAXIS 要看你對該 instance variable 型別有什麼要求,在介面受限的情況下是不是還能實作你想要的類別, 來去決定constness, @lovejomi 只是比較常和 committee member 討論而已, 我覺得要看你對 const 的理解是到語法層還是語意層, 我的習慣是預設全加 const, 還有需要 noexcept 的情況全用 noexcept(bool) 來決定. 預設全加 const 是為了減輕讀碼的負擔還有方便驗證, 不過 pass by value 不會加const因為這情況在介面加 const 是多餘的
作者: eye5002003 (下一夜)   2020-05-14 09:05:00
至今沒寫過一次noexcept,這東西以後被刪除的機率很高我常常寫foo(const std::string &str);既然read only就沒必要整個複製一遍了
作者: Jockey66666 (往事已成追憶)   2020-05-14 22:38:00
如果是string的話直接用string_view吧

Links booklink

Contact Us: admin [ a t ] ucptt.com