问题
I found the following rule in a coding standards sheet :
Do not rely on implicit conversion to bool in conditions.
if (ptr) // wrong
if (ptr != NULL) // ok
How reasonable/usefull is this rule?
How much overload on the compiled code?
回答1:
In the strictest sense, you can rely on implicit conversions to bool. Backwards compatibility with C demands it.
Thus it becomes a question of code readability. Often the purpose of code standards is to enforce a sameness to the code style, whether you agree with the style or not. If you're looking at someone else's standard and wondering if you should incorporate it into your own, go ahead and debate it - but if it's your company's long-standing rule, learn to live with it.
回答2:
In most cases, it's not horrible, but it can be more readable if you type exactly what you mean.
回答3:
That rule puts you in a bind if you ever want to use a class that has an implicit conversion to bool
, such as std::istream
. This code reads a word at a time from a file until EOF is reached:
std::ifstream file("foo.txt");
std::string word;
while (file >> word)
{
// do stuff
}
The stream extraction operator returns a reference to the file stream, which is implicitly converted to bool
to indicate whether the stream is still in a good state. When you reach the end of the file, the test fails. Your coding standard precludes you from using this common construct.
For pointer types, it's not a big deal. The compiler will probably produce about the same code for the implicit conversion to bool
and the explicit test against NULL
. It's a matter of taste at that point - neither one is "better" in an absolute sense. The coding standard is simply trying to enforce a consistent style.
With that in mind, you should absolutely follow the coding standard when dealing with built-in types (pointers, ints, etc.). If you run into a similar situation to the above with a class having a legitimate conversion to bool
, I would raise the issue with your teammates.
回答4:
I wanted to add a historical view to this question.
ANSI C (aka C89/C90) was the first formal specification for C. Along with K&R C, you might notice something peculiar—there is no concept of a boolean. Control flow statements operate on expressions, and their flow is defined based on whether the expression evaluates to 0 or not. The lack of a boolean type is one of the biggest oversights of C. It wasn't until C99 that C gained the _Bool
type, and defined macros for bool
, true
, and false
in stdbool.h (note they are still integers). Likewise, C++ didn't originally have a boolean type, either, gaining it in C++98 with bool
.
This is why there are implicit conversions to booleans. In my opinion, continuing to rely on that is bad design—booleans were added for a reason. true
should always equal true
, and the implicit conversion of all non-zero values as true is unsatisfactory.
NULL
is also just a macro equal to zero, so specifically, for pointers in C++11, you should be using nullptr
to determine if a pointer is null.
if(ptr != nullptr)
{
// Do something with ptr.
}
回答5:
Sometimes I think this rule can be broken, when e.g. dealing with standard libraries which return int
instead of bool
(for compatibility with C89).
However, this rule generally leads to easier-to-understand code. It's even enforced in languages like C# and it's not complained about too much there, so there are no major downsides to following this rule other than having to get used to it.
回答6:
This won't affect the compiled code at all.
As for how useful it is - it'll certainly aid comprehension for people coming from languages such as Java/C#. It'll make it more explicit what you're checking for. It'll throw a warning if you start comparing ints to NULL (and thereby indicate that you're hazy about the type of the variable in question). I personally prefer the first form, but it's not a totally unreasonable requirement.
回答7:
I dislike this rule very much. It is idiomatic in C++ to use the implicit conversion to bool for pointer types (and of course for boolean types). IMO, it is much easier to read
bool conditionMet = false;
while (!conditionMet) // read as "while condition is not met"
{
/* do something */
}
than it is to read this:
bool conditionMet = false;
while (conditionMet == false) // read as "while conditionMet is false"
{
/* do something */
}
It's the same for pointers. Also, by introducing the unnecessary comparison, you're introducing yet another opportunity to mistype and end up with an assignment instead of a comparison, which of course will produce undesired results. In cases where you're using ints as bools, as with old C code, I think you should also use the implicit conversion to bool.
回答8:
A rule that adds zero benefit is a rule you can profitably delete.
回答9:
That's an impressively stupid rule.
if (ptr != NULL) // ok
then why not
if ((ptr != NULL)==true)
来源:https://stackoverflow.com/questions/1331292/c-rely-on-implicit-conversion-to-bool-in-conditions