翻译《有关编程、重构及其他的终极问题?》——4.小心--操作符,请把表达式放在括号中

来源:互联网 发布:oracle查看数据库 编辑:程序博客网 时间:2024/04/27 18:15

翻译《有关编程、重构及其他的终极问题?》——4.小心?:操作符,请把表达式放在括号中

标签(空格分隔): 翻译 技术 C/C++
作者:Andrey Karpov
翻译者:顾笑群 - Rafael Gu
校验者:高国栋
最后更新:2016年12月04日


本书背景说明、总目录等介绍,可以跳转到以下链接进行查看:
http://blog.csdn.net/headman/article/details/53045891

欢迎大家转载,但请附上原作者以及翻译者的名字、原文出处,以尊重光荣的劳动者。


4.小心?:操作符,请把表达式放在括号中

这次我们从Haiku项目(从BeOS继承的项目)选取代码,PVS-Studio检测到的错误是:V502 Perhaps th ‘?:’operator works in a different way than it was expected. The ‘?:’ operator has a lower priority than the ‘-’ operator(译者注:大意是说这个?运算符优先级比-运算符低,所有可能表达式并非写代码的人所期望的).

bool IsVisisble(bool ancestorsVisible) const{    int16 showLevel = BView::Private(view).ShowLevel();    return (showLevel - (ancestorsVisible) ? 0 : 1) <= 0;}

解释
如果我们去查看C/C++运算符优先级,我们会发现三元运算符?:有很低的优先级,甚至比/,+,<等运算符的优先级还低。所以,上面的代码就没有按照编写者预想的方式工作。

那个编写者设想:?运算符会按照下面的方式执行:

(showLevel - (ancestorsVisible ? 0 : 1)) <= 0

但是这个表达式实际上是按照下面的方式执行的:

((showLevel - ancestorsVisible) ? 0 : 1) <= 0

这个错误发生在非常简单的代码中,这说明了?:操作符有多危险。当使用?:操作符时,很容易犯错误,而且在更复杂的情况立,对代码也是一种纯粹的伤害:它不光是让你犯错误,而且还会让你的代码非常难读。

真的得小心的使用?:运算符。我见过很多bug都和这个运算符的使用有关。

正确的代码

return showLevel - (ancestorsVisible ? 01) <= 0;

建议
在我之前写的文章里,我们已经讨论了三元运算符所带来的问题,而且从那时起我对这些问题也变得更敏感。上面的例子也说明了之类的运算符是多么容易带来问题,即使实在很短且简单的表达式中,因此我会修改我在之前写的文章中的建议。

我不是建议完全不使用?:运算符。其实它是有用的,甚至在某些情况下是必须的。但是,请一定不要过度使用它,一旦你决定使用它,请看看我的建议:

一定要把三元运算符表达式放在括号里。假设你有如下表达式:
A = B ? 10 : 20;
你应该写成这样:
A = (B ? 10 : 20);
是的,这个括号有些多余,但当你的同事以后在重构中在这个表达式中增加其他变量时,它会保护你的代码:
A + X + (B ? 10 : 20);
如果没有括号,你可能会忘掉?:运算符是低优先级的,然后偶尔某个时候你的程序就出问题了……虽然有了额外的保护,但如果你把“X+”写在括号里面了,这样就会导致同样的错误。

0 0
原创粉丝点击