Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting false to pointer type void*?

Can someone explain me what is going on here...?

I had this code:

#include <fstream>
#include <string>
#include <iostream> 
int main(){   
    std::ifstream file("test.txt");    
    std::string x;
    while (true) { 
        if (!(file >> x)) return 0;
        std::cout << x << "\n";   
    }
}

...compiles fine, does what it is supposed to do, no problem so far. Sometimes I dont like the ! so much, because it can be overlooked easily, so I replaced the if with

if ((file >> x)==false) return 0;  

..and suddenly my compiler (gcc 4.8.5) complains with a warning:

 warning: converting ‘false’ to pointer type ‘void*’ [-Wconversion-null]
     if ((file >> x)==false) return 0;

and this is where I am starting to be puzzled. Where is the void* coming from? Doesnt >> return a reference that should be casted to a bool? Why is false converted to void*? Why isnt the same warning triggered when I dont explicitly write false?

Out of curiosity I also tried this:

if ((file>>x)==true) return 0;

which causes a storm of errors starting with

error: no match for ‘operator==’ (operand types are ‘std::basic_istream<char>’ and ‘bool’)
 if ((file>>x)==true) return 0;
              ^

and now I am completely lost. How is false a differnt bool than true? Different values of course, but I always thought true and false are of same type.

like image 802
463035818_is_not_a_number Avatar asked May 09 '17 08:05

463035818_is_not_a_number


1 Answers

Recall that C++ has operator overloads. In particular, std::basic_istream overloads operator!.

Alas, there is no enforcement that operator overloads are semantically consistent, so there is no overload for == between an istream and a bool. Thus the comparison with true fails. However, the compiler is also allowed to apply implicit conversions in order to make an expression compile - in this case false may be implicitly converted to a null pointer, and basic_istream has an overload of operator void* (though apparently that was replaced with operator bool in C++11 - presuambly to fix the inconsistency).

like image 159
Oliver Charlesworth Avatar answered Oct 29 '22 22:10

Oliver Charlesworth