Search code examples
c++nullptr

comparison between nullptr and boolean


While I was experimenting with null pointers, I tried to write a code to check whether a pointer was null or not:

#include <iostream>
using namespace std ;
int main(){
    int *p = 0;
    if(!p == true){
        cout<<"nullptr\n";
    }
    else{
        cout<< "no\n";
    }
    return 0;
}

which worked fine without any error but when I tried this (which according to me was basically the same thing but is clearly not):

#include <iostream>
using namespace std ;
int main(){
    int *p = 0;
    if(p == false){
        cout<<"nullptr\n";
    }
    else{
        cout<< "no\n";
    }
    return 0;
}

I got an error: "error: ISO C++ forbids comparison between pointer and integer [-fpermissive]"


Can anyone tell me how are these two codes different and why am I getting an error in the second code?


Solution

  • This has to do with the difference between implicit and explicit conversions, and the special status of the bool type with respect to explicit conversions.

    Generally, while you can convert between integers and pointers (either direction), you can only do it explicitly with a cast. No cast means no conversion and you get an error.

    The special exception here comes from the special treatment of the bool type and the special status of "boolean contexts". Basically, there are a few syntactic contexts:

    • the conditional expression operand of an if, while or for statement
    • the operand of a ! unary operator
    • the first operand of a ?/: ternary operator
    • the operands of &&/||

    which are "boolean contexts" -- the operand must be a bool value -- and where operands of other types may be implicitly converted to bool even if such conversions normally require an explicit cast

    That shows why your first example works -- you're using a unary ! which is one of those special boolean contexts which allows conversion to bool as if there was an explicit cast present.

    This is nothing in particular to do with pointers -- the same thing happens with any user defined (class) type that has an explicit operator bool conversion defined for it.