2

Why we can't directly assign nullptr to a bool object? For example, the flag object's assignment causes an error. Visual Studio compiler gives that: "C++ a value of type cannot be assigned to an entity of type".

int main(){

    int x = 10;
    int *ptr = &x;
    bool flag = ptr;
    
    flag = nullptr; 

}

but below version works fine.

int main(){

    int x = 10;
    int *ptr = &x;
    bool flag = ptr;
    ptr = nullptr;
    
    flag = ptr;

}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
terto
  • 107
  • 4
  • Technicalities aside, why would you want to write `flag = nullptr;` instead of `flag = false;`? – alter_igel Dec 21 '20 at 22:58
  • 3
    `nullptr` is a `nullptr_t` which is not a pointer type, it is just implicitly convertible to pointers of any type. To convert from `nullptr` to `bool` you need two conversion, one to get some pointer, then another to `bool` and the compiler will not try to use two implicit conversions. – François Andrieux Dec 21 '20 at 23:10
  • Thank you for your answer. So, it has a different type and when you need to assign it to a boolean object, firstly you need to assign it to a real pointer. That is fine but why we don't have a similar problem for int or double types? They are distinct types as well but we can directly assign them to boolean objects. – terto Dec 21 '20 at 23:15
  • Hi @alterigel Igel, I'm just trying to understand standard behaviors. – terto Dec 21 '20 at 23:22
  • 1
    @terto because the standard defines implicit conversions for integers/doubles to bool. No such conversion is defined for `nullptr_t`. If you want to know the WHY, ask the standards committee. – Remy Lebeau Dec 22 '20 at 02:29

1 Answers1

8

It's kind of tricky. We have to carefully examine the C++ standard. First, "Standard Conversions" states:

  • All pointers have implicit conversion to boolean (per [conv.bool])

And this conversion simply just converts null pointers to false. So it seems like we should be able to directly assign a null pointer constant to a boolean, right?

Well, kind of.

See, the actual definition for nullptr states that it is an instance of std::nullptr_t, which is a distinct type that is NOT actually a pointer type. However, it can be converted to a pointer type! (Per [lex.nullptr]).

Still seems like it should be possible, right? nullptr is convertible to a pointer type, which is convertible to a boolean.

However, a standard conversion (back to [conv]) sequence can only apply conversions in a specific order. This order allows only ONE of boolean OR pointer conversion.

So, the two conversions that we need will not happen implicitly. We would have to explicitly do one of them for the compiler. For example:

flag = static_cast<int*>(nullptr);

Or, possibly simpler

flag = bool{nullptr}

Or even simpler:

flag = {nullptr}

But at that point, you might as well just use false :-)

AndyG
  • 39,700
  • 8
  • 109
  • 143