6

I have a coworker who routinely does an explicit cast to bool in conditionals, as in:

SomeType *ptr = /* some value */;
if (static_cast<bool>(ptr)) {
    // do something
}

But I haven't been able to find a good reason for such verbosity. Any ideas?

Edit: The coworker says it’s about clarity and being explicit, but I don’t find this explanation to be very compelling. I brought the question here to see if other C++ experts recommend this, and if so, perhaps a more compelling argument would emerge.

squatch
  • 61
  • 3
  • 2
    Some coding guidelines may forbid using implicit conversions in conditionals. However, `if (ptr != nullptr)` is usually preferred in such cases. – Kit. Nov 02 '19 at 19:50
  • 5
    The obvious answer to me is to take a minute to ask your coworker. – chris Nov 02 '19 at 19:53
  • @chris: Yes, that’s a good place to start, and in fact, I did. Edited question to include the details. Thanks! – squatch Nov 03 '19 at 20:22

3 Answers3

7

Broadly speaking, there is no objectively good reason to do this. For pointers, it's actually negatively useful. Pointer conversion to bool is a well-defined operation in C++ and has been since the days of C (and likely before). It's a basic idiom that every C++ programmer needs to learn. Explicitly doing the conversion sends the message that an explicit conversion is somehow different from the implicit contextual conversion, which it is not.

Also, a user who doesn't know what if(ptr) does probably also doesn't know what converting a pointer to bool will do at all. So if(static_cast<bool>(ptr)) can't even be defended as being more clear; if(ptr != nullptr) is far more clear as to what's going on to a neophyte.

walnut
  • 21,629
  • 4
  • 23
  • 59
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    `if(ptr != nullptr)` in this case. `if (ptr)` idiom is so... so... idiomatic for C and for C++. Even the `std::unique_ptr` and `std::shared_ptr` support the idiom. – Eljay Nov 02 '19 at 20:26
  • 1
    @Eljay: It's an evil idiom, which breaks the [principle of least astonishment](http://wiki.c2.com/?PrincipleOfLeastAstonishment) for people who don't already know it. Used `if (ptr != nullptr)` like a boss. +1 on Nicol's answer. – einpoklum Nov 02 '19 at 20:39
2

if (static_cast<bool>(ptr)) is completely equivalent to if (ptr).

Maybe your colleague thinks using static_cast adds some clarity to the code.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • 4
    Not sure what clarity it adds. If you wanted to make the condition clearer, you would write `if(ptr != nullptr)`. – walnut Nov 02 '19 at 19:50
  • @uneven_mark I'm not sure either. I myself wouldn't use a `static_cast` here. – HolyBlackCat Nov 02 '19 at 19:53
  • Although `if(ptr)` is a very old idiom (one that I'm using myself every day!) reading the standard, I am now not really sure about that. 7.14 says "A prvalue of [...], pointer, or [...] can be converted to a prvalue of type bool". Now, `ptr` here isn't a prvalue, methinks. It doesn't compute the value of an operator, nor does it initialize a bitfield or object. So, in the strictest sense... hmm... if one wrote `if(ptr != nullptr)` then it sure _would_ compute the value of an operator, so that'd be legitimate. – Damon Nov 02 '19 at 20:05
  • 1
    @Damon When citing the standard, use the stable section names, e.g. here you cite [conv.bool]. The numeric section counters often change between the standard versions/drafts. – walnut Nov 02 '19 at 20:21
  • 2
    @Damon The condition is *contexually converted to bool*, which also incurs *lvalue-to-rvalue* conversion. The boolean conversion can happen after that. – walnut Nov 02 '19 at 20:26
1

Since C++11, you've been able to specify an explicit bool conversion, which is only triggered when using in situations such as if (myObj) { … } but not in situations like bool b = myObj;. The statements are equivalent, but your co-worker may have been trying to provide the "explicit" nature of the conversion in syntax only. To summarise, you don't need the static_cast<bool>(myObj), and following C++11, you've got type-safety provided.

Mark Ingram
  • 71,849
  • 51
  • 176
  • 230