views:

385

answers:

8

In the following code, what is the benefit of using (!!p) instead of (p != NULL)?

AClass *p = getInstanceOfAClass();
if( !!p )
  // do something
else 
  // do something without having valid pointer
+10  A: 

That's a matter of style, in fact they are equivalent. See this very similar question for discussion.

IMO comparing against null pointer is clearer.

sharptooth
+3  A: 

As far as I can see, it's just a shorter way to convert it into a boolean value. It applies the ! twice, though, whereas p != NULL does one comparison. So I guess the benefit is just shorter code, albeit more cryptic if you don't know what !!p is supposed to mean.

Twisol
A: 

See this and this.

Anton Gogolev
+11  A: 

It is pretty much the same, although I consider the !!p to be bad style, and usually indicates a coder trying to be clever.

iWerner
If it took you an hour to write the clever code, it'll take you two to understand it after a few weeks.
Twisol
I fully agree. It should've read "trying to be clever, and failing"
iWerner
A: 

They are the same, but I recommend to use

NULL != p

It is more readable.

Cătălin Pitiș
Michael Foukarakis
The readability of it is debatable. Personally, I find it *less* readable, simply because it doesn't read naturally. I usually say 'if p is not NULL' not 'if NULL is not p'.
Bojan Resnik
Yes but it does prevent people missing an erroneous "p = NULL" as the compiler would pickup "NULL = p".
ChrisBD
yeah, it's actually much safer and better notation to put expected values on the left, just taht nobody really does it.
Matt Joiner
In "If zero is not the number of apples I have" vs. "If the number of apples I have is not zero", I find the second more readable, thus "if (apples != 0)". That is, object being compared on the left, constant on the right. This is usually cited with respect to = vs. ==, but Unit Testing and Lint pick these up easily.
Kaz Dragon
+1, no need for a down vote, it is the author's recommendation and there is not really anything wrong with it.
stefaanv
@ ChrisBD: Any compiler I know also picks up "p = NULL". Unless you have warnings disabled, which you should never do.
DevSolar
@DevSolar: Exactly the reason I preffer NULL != p, and not p != NULL. And you get used with NULL == p, so it can be applied by reflex when NULL != p.@stefaanv: Thanks :). It is my recommendation, based on past experience. It seems that many people disagreed with me.
Cătălin Pitiș
I understand why some people put constants on the left in conditions, but I object to calling that notation 'more readable' in general. That said, nowadays all compilers emit warnings when assignment is used as condition, so I see no point in using the 'constant on the left' style.
Bojan Resnik
@Bojan: First: Developers tend to ignore warnings. Second: it is more readable than double negation.
Cătălin Pitiș
If a developer ignores code warnings, it is the developer that needs to be fixed, not the code. And "getting used" to some workaround for sloppy developers is still what I call "mental speedbump" for those who refuse to wrap their mind around such kludges. (Yes, I feel strongly about this.)
DevSolar
I agree it is more readable than double negation, however I objected to your claim that it was more readable than both `!!p` and `p != NULL`. Developers who ignore warnings deserve to spend hours searching for an 'assignment in condition' bug - for no other reason than to learn not to ignore the warnings. Like DevSolar, I also feel strongly about introducing workarounds for sloppy development practices.
Bojan Resnik
I never said it is more readable than p != NULL (please quote me, if I did). I compared with !!p, which was the subject of the question I replied to.
Cătălin Pitiș
OP: 'What is the benefit of using (!!p) instead of (p != NULL)'Catalin: 'They are the same, but I recommend to use `NULL != p` It is more readable.'Perhaps its just me, but I read this as '`NULL != p` is more readable than both of them.'
Bojan Resnik
A: 

Do !!NOT use double negation. A simple argument is that since C++ is a limited English subset and english just does not have a double negation then english speakers will have a lot of difficulty to parse what is going on.

Pasi Savolainen
I see what you did there...
Twisol
Except if you also took Latin classes, then the double negation -- depending on context -- does not cancel out, but the meaning of the negation is amplified.
MP24
Except that ! (C++ is a limited subset of English).
outis
@MP24? Care to give an example? I only know of the opposite (e.g. “non ignoro”) where the double negation serves to amplify a *positive* assertion (in this case: “I know *very well*” instead of “I don’t not know”). As for English: “ain’t got no money” is perfectly valid vernacular (Steven Pinker even uses it as an example) where (in the meaning) the double negation is *dropped* in favour of a simple negation: “no” replaces “any”. The same is true in (standard) French, “je n’ai pas d’argent” would literally translate to “I haven’t got no money” but the meaning is the opposite. `</off topic>`
Konrad Rudolph
A: 

There is no difference in the given example.

However the assumption that this applies to all cases is incorrect. a = not not b is not the same as a = b, as far as integer types are concerned.

In C, 0 is false. Anything but 0 is true. But not 0 is 1, and nothing else. In C++, true casts to 1 as an integer, not only for backward compatibilty with C, but because 1 is not 0, and 1 is the most common value used to denote true in C bool types, including the official C bool type, and BOOL used in Win32.

While for the example code given, !!p is unnecessary because the result is cast to a bool for evaluation of the if condition, that doesn't rule out the use of !! for purposes of casting booleans to expected integer values. Personally in this example, to maximize the probability that type changes and semantics are clear, I would use NULL != p or p != NULL to make it absolutely clear what is meant.

This technique is known as the double-bang idiom, and this guy provides some good justifications.

Matt Joiner
Those justifications are not valid in this instance.
Keith Randall
Actually in this context if(p) and if(!!p) *are* identical. This is because the condition of 'if' is converted to bool and tested, which is exactly what !! ends up doing. Re the linked answer, in C++ the kernel guys could have cast their value to a bool.
Richard Corden
"While for the example code given, !!p is obviously not needed," perhaps I should make this clearer.
Matt Joiner
+6  A: 

I thing GMan’s original comment should be the accepted answer:

I wonder what's wrong with just if (p)

The point is: nothing is wrong with it, and this should be the preferred way. First off, !!p is “too clever”; it’s also completely unnecessary and thus bad (notice: we’re talking about pointers in an if statement here, so Anacrolix’ comment, while generally valid, doesn’t apply here!).

The same goes for p != NULL. While this is possible, it’s just not needed. It’s more code, it’s completely redundant code and hence it makes the code worse. The truest thing Jeff Atwood ever said was that “the best code is no code at all.” Avoid redundant syntax. Stick to the minimum (that still conveys the complete meaning; if (p) is complete).

Finally, if (p) is arguably the most idiomatic way to write this in C++. C++ bends over backwards to get this same behaviour for other types in the language (e.g. data streams), at the cost of some very weird quirks. The next version of the standard even introduces new a syntax to achieve this behaviour in user-defined types.

For pointers, we get the same for free. So use it.

/EDIT: About clarity: sharptooth writes that

IMO comparing against null pointer is clearer.

I claim that this is objectively wrong: if (p) is clearer. There is no possible way that this statement could mean anything else, neither in this context nor in any other, in C++.

Konrad Rudolph
I follow this. if( p ) does it all, does it short, does it clear. (And some might also call the additional benefit of not using 'NULL', as they prefer '0')
stijn
I prefer to reserve if (x) for boolean types, and if (x != nullptr /* or NULL */) for pointer types. That way your pointer checks stand out in code and are easy to search for.
Bill
"There is no possible way that this statement could mean anything else" - There is also no possible way that if (p != NULL) could mean anything but p does not equal NULL, whatever NULL may be.
Ed Swangren
@Ed: yes, but `p != NULL` gives redundant information. Where are the benefits compared to `if (p)`?
Konrad Rudolph