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