C ++依赖于隐式转换到条件中的bool?

时间:2009-08-25 22:05:04

标签: c++ coding-style implicit-cast

我在coding standards sheet中找到了以下规则:

  

在条件下不要依赖隐式转换为bool。

     

if(ptr)//错误

     

if(ptr!= NULL)// ok

此规则的合理性/实用性如何?

编译代码有多少重载?

9 个答案:

答案 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类型,并为booltrue定义了宏,和stdbool.h中的false(注意它们仍然是整数)。同样地,C ++最初也没有布尔类型,使用boolC++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)