7

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
sharptooth
  • 167,383
  • 100
  • 513
  • 979
Juan Macek
  • 270
  • 1
  • 3
  • 10
  • 23
    I wonder what's wrong with just `if (p)`. – GManNickG Oct 22 '09 at 08:15
  • 3
    You should always be suspicious operators are overloaded. It is possible `!p` or `!=` have special behaviors. – Kobi Oct 22 '09 at 08:22
  • Of course, doing it this way is terrible design. – GManNickG Oct 22 '09 at 08:26
  • 2
    Kobi - I can't remember, but do the overloaded operators also apply to *pointers* to an object? It seems like they wouldn't; if I'm right, in this case there aren't really any overloaded operators issues. (Whether or not I'm right, though, that's a great point and worth a +1 on its own) – Twisol Oct 22 '09 at 08:28
  • 1
    They can indeed `Object* operator+(Object const*, Object const*)` is a valid signature.... – Matthieu M. Oct 22 '09 at 19:02
  • @Matthieu: Appears I forgot nonmember operators! Thanks for the correction. – Twisol Oct 23 '09 at 03:07
  • There's absolutely no point in doing `!!` in this case. This is just someone's rather weird coding style. As Ed noted, with the same degree of success that person might've used `!!!!!!!!` (or any other even number of `!`s) instead of just `!!`. – AnT stands with Russia Oct 23 '09 at 06:39
  • 1
    @Twisol: No, you were right the first time. Operators cannot be overloaded for non-class/non-enumeration types. Non-member overload won't change anything. You can declare it, if you want, but overload resolution will never consider it. In the original example (pointer type) operator overloading is not possible. – AnT stands with Russia Oct 23 '09 at 06:47
  • @Kobi: In general - yes. In this case - no. Operators cannot be overloaded for pointer types. – AnT stands with Russia Oct 23 '09 at 06:48

7 Answers7

11

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

Wernsey
  • 5,411
  • 22
  • 38
9

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.

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
7

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
  • 530,221
  • 131
  • 937
  • 1,214
  • 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 Oct 22 '09 at 10:25
  • 2
    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 Oct 22 '09 at 17:07
  • "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 S. Oct 22 '09 at 22:30
  • @Ed: yes, but `p != NULL` gives redundant information. Where are the benefits compared to `if (p)`? – Konrad Rudolph Oct 23 '09 at 07:32
3

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
  • 2,762
  • 1
  • 17
  • 17
-1

They are the same, but I recommend to use

NULL != p

It is more readable.

Cătălin Pitiș
  • 14,123
  • 2
  • 39
  • 62
  • That's nothing but personal preference & style. – Michael Foukarakis Oct 22 '09 at 08:19
  • 4
    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 Oct 22 '09 at 08:20
  • 3
    Yes but it does prevent people missing an erroneous "p = NULL" as the compiler would pickup "NULL = p". – ChrisBD Oct 22 '09 at 08:35
  • yeah, it's actually much safer and better notation to put expected values on the left, just taht nobody really does it. – Matt Joiner Oct 22 '09 at 09:13
  • 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 Oct 22 '09 at 09:32
  • +1, no need for a down vote, it is the author's recommendation and there is not really anything wrong with it. – stefaanv Oct 22 '09 at 09:34
  • 2
    @ ChrisBD: Any compiler I know also picks up "p = NULL". Unless you have warnings disabled, which you should never do. – DevSolar Oct 22 '09 at 09:48
  • @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ș Oct 22 '09 at 10:29
  • 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 Oct 22 '09 at 11:56
  • @Bojan: First: Developers tend to ignore warnings. Second: it is more readable than double negation. – Cătălin Pitiș Oct 22 '09 at 12:45
  • 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 Oct 22 '09 at 12:57
  • 1
    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 Oct 22 '09 at 13:19
  • 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ș Oct 22 '09 at 13:54
  • 1
    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 Oct 22 '09 at 13:59
-1

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.

Community
  • 1
  • 1
Matt Joiner
  • 112,946
  • 110
  • 377
  • 526
  • Those justifications are not valid in this instance. – Keith Randall Oct 22 '09 at 18:12
  • 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 Oct 22 '09 at 18:55
  • "While for the example code given, !!p is obviously not needed," perhaps I should make this clearer. – Matt Joiner Oct 22 '09 at 22:19
-2

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
  • 2,460
  • 1
  • 22
  • 35
  • 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 Oct 22 '09 at 08:27
  • 2
    Except that ! (C++ is a limited subset of English). – outis Oct 22 '09 at 08:40
  • @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. `` – Konrad Rudolph Oct 22 '09 at 09:59