我在coding standards sheet中找到了以下规则:
在条件下不要依赖隐式转换为bool。
if(ptr)//错误
if(ptr!= NULL)// ok
此规则的合理性/实用性如何?
编译代码有多少重载?
答案 0 :(得分:11)
从最严格的意义上讲,你可以依靠隐式转换来加油。向后兼容C需要它。
因此,它成为代码可读性的问题。代码标准的目的通常是强制执行代码样式的相同性,无论您是否同意样式。如果你正在考虑其他人的标准,并想知道你是否应该将其纳入自己的标准,请继续进行辩论 - 但如果这是你公司的长期规则,那么就要学会忍受它。
答案 1 :(得分:5)
在大多数情况下,它并不可怕,但如果您输入的确切含义,可以更具可读性。
答案 2 :(得分:5)
如果您想要使用隐式转换为bool
的类(例如std::istream
),该规则会将您置于绑定中。此代码一次从文件中读取一个单词,直到达到EOF:
std::ifstream file("foo.txt");
std::string word;
while (file >> word)
{
// do stuff
}
流提取运算符返回对文件流的引用,该引用被隐式转换为bool
以指示流是否仍处于良好状态。当您到达文件末尾时,测试失败。您的编码标准使您无法使用此常见结构。
对于指针类型,这不是什么大问题。编译器可能会为隐式转换为bool
和针对NULL
的显式测试生成大致相同的代码。这是一个品味问题 - 在绝对意义上,任何人都不是“更好”。编码标准只是试图强制执行一致的风格。
考虑到这一点,在处理内置类型(指针,整数等)时,您应该完全遵循编码标准。如果您遇到与上述类似的情况,并且合法转换为bool
,我会向您的队友提出问题。
答案 3 :(得分:3)
我想在此问题中添加历史视图。
ANSI C(又名C89 / C90)是C的第一个正式规范。与K&R C一起,您可能会注意到一些特殊的东西 - 没有布尔值的概念。控制流语句在表达式上运行,并且它们的流程是根据表达式是否计算为 0 而定义的。缺少布尔类型是C的最大疏忽之一。直到C99,C才获得_Bool
类型,并为bool
,true
定义了宏,和stdbool.h
中的false
(注意它们仍然是整数)。同样地,C ++最初也没有布尔类型,使用bool
在C++98获得它。
这就是为什么隐含的转换为布尔值的原因。在我看来,继续依赖于这是糟糕的设计 - 布尔加入是有原因的。 true
应该始终等于true
,并且将所有非零值隐式转换为true是不能令人满意的。
NULL
也只是一个等于零的宏,所以具体来说,对于C ++ 11中的指针,你应该使用nullptr
来确定指针是否为空。
if(ptr != nullptr)
{
// Do something with ptr.
}
答案 4 :(得分:1)
这根本不会影响编译代码。
至于它有多么有用 - 它肯定有助于理解来自Java / C#等语言的人。它会让你更明确地检查你所检查的内容。如果你开始将int比较为NULL(从而表明你对所讨论的变量的类型感到朦胧),它会发出警告。我个人更喜欢第一种形式,但这并非完全不合理的要求。
答案 5 :(得分:1)
有时我认为这条规则可能会被破坏,例如处理返回int
而不是bool
的标准库(为了与C89兼容)。
但是,此规则通常会导致更易于理解的代码。它甚至在像C#这样的语言中得到了强制执行,而且它并没有被过多地抱怨,因此除了必须习惯它之外,遵循这条规则没有重大缺点。
答案 6 :(得分:0)
我非常不喜欢这条规则。在C ++中使用隐式转换为bool指针类型(当然还有布尔类型)是惯用的。 IMO,它更容易阅读
bool conditionMet = false;
while (!conditionMet) // read as "while condition is not met"
{
/* do something */
}
比读这个:
bool conditionMet = false;
while (conditionMet == false) // read as "while conditionMet is false"
{
/* do something */
}
指针也一样。此外,通过引入不必要的比较,您将引入另一个错误输入和结束作业而不是比较的机会,这当然会产生不希望的结果。如果你使用int作为bools,就像旧的C代码一样,我认为你也应该使用隐式转换来bool。
答案 7 :(得分:-1)
添加零利益的规则是您可以有利地删除的规则。
答案 8 :(得分:-4)
这是一个令人印象深刻的愚蠢规则。
if (ptr != NULL) // ok
然后为什么不
if ((ptr != NULL)==true)