Consider the following code compiled with Visual Studio 2015:
#include <iostream>
#include <cassert>
void foo(bool b)
{
std::cout << b;
}
int main()
{
int a;
foo(a = 2); // Getting warning #4800
foo(!(a = 2)); // Not getting any warning
return 0;
}
foo(a = 2)
produces warning 4800 'int': forcing value to bool 'true' or 'false'
, fine.
But foo(!(a = 2))
does not produce the warning. Why? At some point there has been an int-to-bool cast!
foo(a = 2)
is equivalent to bool b = (a = 2)
. The expression a = 2
returns an a
, so it is equivalent to
a = 2;
bool b = a; //Conversion of 'int' to 'bool' -> Warning!
foo(!(a = 2))
is equivalent to bool b = !(a = 2)
. The expression a = 2
returns a
:
a = 2;
bool b = !a; //'!a' is legal => It returns a bool -> No warning!
Note that you can apply operator!
to an int
, which negates the int
, and so returns a bool
. That's why there is no performance warning.