Because in a statically typed language, you want the type of a symbol to represent the set of values it can be bound to. We often have the set {something that passes a truth test, something that fails a truth test} in our programs, so a boolean type is a nice way to represent it.
Now, this is not the same thing defining what exactly the truth test is. It's perfectly reasonable and arguably a good design to have both a narrow boolean type and a wide definition of truthiness.
What's wrong with anything that's not false is true?
If you treat it this way you remove the vast majority of the problems with most C or C++ BOOL implementations.
The low bytes of a pointer being 0 (It can happen on Windows with VirtualAlloc and company) can screw up the works, so avoid assigning a pointer to a BOOL and use BOOL b = !!pointer if you have to break that rule.
Why not make the correct comparison and do BOOL b = pointer != NULL. Now the code says what you mean, is easy to understand, and assigns a boolean value to a bool.
!!p does the same as p!=NULL. The choice is purely stylistic. (!p is equivalent to p==NULL; !!p is therefore equivalent to !(p==NULL). Or, alternatively, p!=NULL.)
Because the properties of other types might not translate. It's probably okay with integer types since (a + b) => (a OR b) and (a * b) => (a AND b) as long as you stay away from upper bounds.
But some semantic maps are less great. Having your compiler help you to ensure you're not implicitly mixing up bad maps can be helpful.
Now, this is not the same thing defining what exactly the truth test is. It's perfectly reasonable and arguably a good design to have both a narrow boolean type and a wide definition of truthiness.