Reputation: 2365
I am interrested wheather standard says anything about possible values of bool
type type after casting it to integer
type.
For example following code:
#include <iostream>
using namespace std;
int main() {
bool someValue=false;
*((int*)(&someValue)) = 50;
cout << someValue << endl;
return 0;
}
prints 1 even though it's forced to store value 50. Does standard specify anything about it? Or is compiler generating some method for type bool as:
operator int(){
return myValue !=0 ? 1 : 0;
}
Also why is casting like following:
reinterpret_cast<int>(someValue) = 50;
forbidden with error
error: invalid cast from type 'bool' to type 'int'
(For all above I user GCC 5.1 compiler.)
Upvotes: 2
Views: 7879
Reputation: 149155
This line *((int*)(&someValue)) = 50;
is at least non standard. The implementation could use a lesser rank for bool (say 1 or 2 bytes) that for int (say 4 bytes). In that case, you would write past the variable possibly erasing an other variable.
And anyway, as you were said in comment, thanks to the strict aliasing rule almost any access through a casted pointer can be seen as Undefined Behaviour by a compiler. The only almost legal one (for the strict aliasing rule) would be:
*((char *) &someValue) = 50;
on a little endian system, and
*(((char *) &someValue) + sizeof(bool) - 1) = 50;
on a big endian one (byte access has still not be forbidden).
Anyway, as the representation of bool is not specified by the standard directly writing something in a bool can lead to true or false depending on implementation. For example an implementation could considere only the lowest level bit (true if val&1 is 1, else 0), another one could considere all bits (true for any non 0 value, false for only 0). The only thing that standard says is that a conversion of a 0 leads to false and of a non 0 leads to true.
But was is mandated by standard is the conversion from bool to int:
4.5 Integral promotions [conv.prom]
...
A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.
So this fully explains that displaying a bool can only give 0 or 1 - even if as the previous operation invoked UB, anything could have happen here including this display
You invoked Undefined Behaviour - shame on you
Upvotes: 4
Reputation: 3560
The way you are using it exhibits UB, because you write outside of the bool variable's boundaries AND you break strict aliasing rule.
However, if you have a bool and want to use it as a an int (this usually happens when you want to index into an array based on some condition), the standard mandates that a true
bool converts into 1
and false
bool converts into 0
, no matter what (UB obviously excluded).
For example, this is guaranteed to output 52
as long as should_add == true
.
int main(){
int arr[] = {0, 10};
bool should_add = 123;
int result = 42 + arr[should_add];
std::cout << result << '\n';
}
Upvotes: 7