Benjy Kessler
Benjy Kessler

Reputation: 7646

Casting nullptr to bool

In the pre-C++11 days it was considered better practice to write:

if (ptr == NULL)

Rather than:

if (!ptr)

This was for two reasons. It is more efficient because it didn't need to cast to bool. And there was no guarantee that the macro NULL would indeed evaluate to the boolean false. Is this still true in C++11? Is it preferable to write

if (ptr == nullptr)

Rather than

if (!ptr)

Or is the second fine now?

Upvotes: 6

Views: 9026

Answers (5)

Benjy Kessler
Benjy Kessler

Reputation: 7646

In C as many people here said it is indeed only a matter of style whether you implicitly cast to a bool or explicitly compare against NULL.

In C++11 however the story is different. nullptr provides type safety. Consider the following examples:

auto ptr = accessVal();
if (ptr == nullptr) {cout << "Pointer is null."};

vs.

auto ptr = accessVal();
if (!ptr) {cout << "Pointer is null."};

The first will only compile if ptr is a pointer. The second will compile if ptr can be implicitly casted to a bool.

To sum up the advantage of implicitly casting to bool is brevity. The advantage of comparing to nullptr is type safety. I think in most cases the benefit if type safety outweighs the benefit of brevity. Indeed this is the main reason for introducing the nullptr in C++11 in the first place.

Upvotes: 3

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145289

Re

In the pre-C++11 days it was considered better practice to write:

if (ptr == NULL)

Rather than:

if (!ptr)

No, not by informed people.

This was for two reasons. It is more efficient because it didn't need to cast to bool.

No, the two expressions are equivalent, one is not more efficient than the other. And a “cast” is a notation. It's meaningless to confuse that with execution efficiency.

And there was no guarantee that the macro NULL would indeed evaluate to the boolean false.

There is indeed such a guarantee.

Is this still true in C++11?

It's still all false in C++11, and in C++14, and will still be false in C++17.

Upvotes: 5

AndyG
AndyG

Reputation: 41110

Smart pointers like unique_ptr and shared_ptr have implicit conversions to bool that checks the internal pointer against nullptr, so the second is preferred in those cases, because the intent is well understood.

For raw pointers, I don't know if there's any actual guidance, but ptr != nullptr certainly explains the intent much more clearly (and what types are involved).

Upvotes: 4

JuniorCompressor
JuniorCompressor

Reputation: 20025

It's a matter of readability since the compiler is advanced to handle optimally both cases. One exception is if you create your own pointer class where !ptr must be evaluated by your code and suddenly the two syntaxes are not necessary equivalent. So I suggest when writing generic code to use if (ptr != nullptr) syntax.

Upvotes: 2

Bartek Banachewicz
Bartek Banachewicz

Reputation: 39380

It is more efficient because it didn't need to cast to bool.

I'd slap an ol' [citation-needed] at that. I doubt any modern compiler would make that count.


if (ptr) is perfectly fine and probably more semantically correct, if you're using that value to represent a canonical "lack of value".

I'd only expect to see if (ptr != nullptr) if someone was actually utilizing the "null" value for pointer arithmetic, but even then it's really sketchy.


That being said, a lot of times you can just get away with... not checking that at all. If the pointer's nullability is used to represent a nullable data field, use optional. If you are initializing it in case it's empty, use value_or idiom. If it's just a weak reference and the contract on value is outside, an assert will do.

Upvotes: 8

Related Questions