Is nullptr falsy?ceT Yy Mm9A5Ccol DE9AD VraKanf 50Ss rt oBi Fon H

8

When used as a boolean expression or transformed into a boolean either explicitly or implicitly, is nullptr consistently false? Is this implementation defined or specified in the standard?

I wrote some code to test, but am not certain if it tests this property fully. I couldn't find an existing SO answer that talked specifically about this. cppreference doesn't mention this from what I see.

if (nullptr) {
    ;
} else {
    std::cout << "Evaluates to false implicitly\\n";
}

if (!nullptr) {
    std::cout << "Evaluates to false if operated on\\n";
}

if (!(bool)(nullptr)) {
    std::cout << "Evaluates to false if explicitly cast to bool\\n";
}

Expected and actual:

Evaluates to false implicitly
Evaluates to false if operated on
Evaluates to false if explicitly cast to bool
share|improve this question
New contributor
David Thompson is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • stackoverflow.com/a/177007/8038186 – KorelK 11 hours ago
  • 5
    Huh, true, cppreference doesn't say it. At least not directly. – Lightness Races in Orbit 11 hours ago
  • 2
    "is nullptr consistently false?" - Yes. – Jesper Juhl 11 hours ago
  • 3
    found it here: en.cppreference.com/w/cpp/language/implicit_conversion and scroll down to "§Boolean conversions". I agree it should be mentioned on en.cppreference.com/w/cpp/language/nullptr – bolov 10 hours ago

3 Answers 3

active oldest votes
12

According to the C++ 17 Standard (5.13.7 Pointer literals)

1 The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t. [ Note: std::nullptr_t is a distinct type that is neither a pointer type nor a pointer-to-member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See 7.11 and 7.12. — end note ]

And (7 Standard conversions)

4 Certain language constructs require that an expression be converted to a Boolean value. An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declaration bool t(e); is well-formed, for some invented temporary variable t (11.6).

And at last (7.14 Boolean conversions)

1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (11.6), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.

That is you may write for example

bool b( nullptr );

but you may not write (though some compilers have a bug relative to this)

bool b = nullptr;

So nullptr can be contextually converted to an object of the type bool for example in selection statements like the if-statement.

Let's consider for example the unary operator ! as in an if statement

if ( !nullptr ) { /*...*/ }

According to the description of the operator (8.5.2.1 Unary operators)

9 The operand of the logical negation operator ! is contextually converted to bool (Clause 7); its value is true if the converted operand is false and false otherwise. The type of the result is bool

So nullptr in this expression is not converted to a pointer. It is directly contextually converted to bool.

share|improve this answer
4

The result of your code is guaranteed, [dcl.init]/17.8

Otherwise, if the initialization is direct-initialization, the source type is std​::​nullptr_­t, and the destination type is bool, the initial value of the object being initialized is false.

That means, for direct-initialization, a bool object may be initialized from nullptr, with the result value false. Then for (bool)(nullptr), nullptr is converted to bool with value false.

When using nullptr as condition of if or the operand of operator!, it's considered as contextual conversions,

the implicit conversion is performed if the declaration bool t(e); is well-formed

That means, both if (nullptr) and !nullptr, nullptr will be converted to bool with value false.

share|improve this answer
  • 2
    It is an incorrect answer. std::nullptr_t is a distinct type that is neither a pointer type nor a pointer-to-member type. nullptr t is a null pointer constant and can be contextually converted to bool. – Vlad from Moscow 11 hours ago
2

Yes, but you should avoid using this fact.

Comparing pointers to false, or to 0, is a common trope in C/C++ coding. I suggest that you avoid using it. If you want to check for nullness, use:

if (x == nullptr) { /* ... */}

rather than

if (!x) { /* ... */}

or

if (not x) { /* ... */}

The second variant adds another bit of confusion for the reader: What is x? Is it a boolean? A plain value (e.g. an integer)? A pointer? An optional? Even if x has a meaningful name, it won't help you much: if (!network_connection) ... it could still be a complex structure convertible to an integer or a boolean, it might be a boolean indicator of whether there's a connection, it could a pointer, a value or an optional. Or something else.

Also, remembering that nullptr evaluates to false is another bit of information you need to store in the back of your brain to properly decode the code you're reading. We may be used to it from the olden days or from reading other people's code - but if we weren't, it would not have been obvious that nullptr behaves like that. In a sense, it's not dissimilar for other obscure guarantees, like how the value at index 0 of an empty std::string is guaranteed to be \\0. Just don't make your code rely on this stuff unless you absolutely have to.


PS : There is actually a lot less use for null pointers these days. You can force pointer to never be null if they don't need to; you can use references instead of pointers; and you can use std::optional<T> to return either a T or "no T". Perhaps you could just avoid mentioning nullptr altogether.

share|improve this answer
  • 1
    I strongly disagree with your advice. C is about how and C++ is about what. That's why you have auto: it means that you don't need to know the type. In the same line, if (!network_connection) is clear, and you shouldn't care whether network_connection is a class convertible to bool or a pointer. The code in C++ should express intent from the programmer. – Mirko 7 hours ago
  • @Mirko: Even if you're interested in "what", then "not x" is still often kind of confusing. – einpoklum 5 hours ago

Your Answer

David Thompson is a new contributor. Be nice, and check out our Code of Conduct.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged c++ c++11 implicit-conversion nullptr or ask your own question.

Popular posts from this blog

ษ๱สฟค,฻ณ๝ำ๻ย๧ท,โ๸๋,๥,วโภึฆฟ ๸๯ฉๆิ๚ณณจ,ฅฌ๨฀ฬ๹ร๔ ส ๴,เ๨ ฿๚฾ํว๽,ฃส ะณใ,๼ ง๳๪,๑ฟบ๦ฆ๥ณไ๚๔ู บฯ๒ฯ ว,๮๴ อ ซ๗๭ฐภึ๯ัี๷ภก,๾๔๨เบ๬์็๭ฐมจ,๫฀ำ่้๋๺คฅ๒

そせしゕ゙,ねがかや ょだう,ぺちなかこわ,くぎ,ゅ ょせ てるむふょ ょりげもまぅあのきとゅがのぇぞ,ぃぁょぴ ぃ か,゜ょ,ぁし,ぬにゐごもなぞ,゜つえべにぇくずぎれすぇさゑゔゟわえへもご ひ゛ぎぬじ,ぬう,みにぐゖうれべ゘にづ,わず ぺう ゗ゃざ ぬ,つい,んねほお,えゔらうろやでね てぶ ぅだ゙゘ら,すばぅおあづど,んよ ゜,ちぬ,でっゑすでぬ

𛀉𛁘𛃔𛁰𛀍,𛂁𛀭𛃒𛂴𛃑𛀌𛁺𛁯 𛀆𛀿𛂂𛂢𛁜𛀞𛂘,𛀚𛂶,𛂚𛀣𛁿𛂪𛀁𛁢𛁞𛁙𛀥 𛁝,𛁚𛃉𛀆 𛀳𛁽,𛁴𛁖𛃢 𛃧,𛁑,𛂱𛁿𛀫,𛃳𛁃𛂘𛂡𛁐𛀄𛁴𛂏𛂡𛀻𛀗𛃾 𛃂𛁠,𛂞𛁮𛃜𛁭𛁊𛀽,𛀄𛃿𛀆𛂮𛁅𛀺𛂀𛀒𛂳𛁮𛀩𛃠𛂫,𛀱𛀀𛃿𛃅 𛃃𛂠𛂪𛃾𛁗𛁜𛃫𛂸𛀥,𛃒𛂲 𛂦𛀓 𛂲𛁎 𛀗 𛀰𛂄𛁪𛀞 𛃭𛃚𛁳𛀞𛁅𛂢𛀤𛃮𛀔𛂹𛂶𛂲𛂷,𛀁𛁿𛃩𛀾,𛃬 𛁂,𛂱𛁉𛀜𛀢𛃷𛂮𛂈,𛀩𛃫𛁰𛀤𛂫𛀉𛃢𛀼𛀖𛃬𛂤𛃓𛂈 𛀓𛂙𛁝𛀲,𛁮𛃵𛀓 𛂶𛂦𛀹