0

I have following program

int a = 216;
bool* v = (bool*)((void*)&a);
std::cout << (*v == true) << endl;

I would expect this program to print out true or false but instead it prints out 216. I have compiled it with g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2. Is it expected behaviour or some bug? Why would equality operator return different type than bool?

--------- EDIT ---------

My intention is not to cast to void but to make v storing 216 in its memory location. Alternative program may look like this:

bool v;
int a = 216;
memcpy(&v, &a, sizeof(bool));
std::cout << (v == true) << endl;

Or I can take uninitialized bool pointer which points to some random value which happens to be e.g. 216.

Trismegistos
  • 3,821
  • 2
  • 24
  • 41
  • 1
    `v` points to a temporary (created from all the casts) which is invalid at the end of the line that created it. Maybe make `v` a `bool` not `bool*`. Bear in mind that `v` will always be true, here it points to valid memory location (the address of `a`). Try `bool v = (&a);` – Niall Oct 20 '14 at 12:04
  • [Cannot reproduce](http://ideone.com/aTWLm8). I do not see `216` in `stdout`. – Cory Kramer Oct 20 '14 at 12:05
  • @Cyber you do see `0` instead of the expected `1` though. _Horray for UB!_ – Baldrickk Oct 20 '14 at 12:21
  • 1
    Since `p` isn't actually pointing to a `bool` like you said it is, the code is undefined, and 216 is a perfectly reasonable result. (The output is 216 because if `p` is a `bool*`, `*p == true` can be been replaced with `*p` and the compiler did that.) – molbdnilo Oct 20 '14 at 12:33

2 Answers2

5

The only valid thing you can do after casting a pointer to void*, is to cast it back to the original pointer type (in your case int*). You cast it to bool* though, which brings you into the domain of undefined behavior. Or, in other words, you can't expect anything to happen a certain way.

You might think getting rid of the cast to void* will resolve this. However, dereferencing a pointer after casting it to a different pointer type also results in undefined behavior.

The expected output can easily be achieved this way though :

bool v = (bool) a;
std::cout << (v == true) << std::endl;
Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
  • Casting to void was only done to point to some memory location which has 216 in it. You may try to do it by different means e.g. you can write 216 to memory location reserved for bool. Result will be the same. – Trismegistos Oct 20 '14 at 12:28
  • @Trismegistos : it sounds like you wrote an integer value into a `bool` variable by means of casting a `bool*` to an `int*`and then dereferencing the `int*` to set the value. If so, please check the second paragraph of my answer - that results in undefined behavior too. – Sander De Dycker Oct 20 '14 at 12:35
  • @Trismegistos : from the update to your question, you seem to have used `memcpy` with two different pointer types. This is undefined behavior again, for basically the same reasons : you're trying to treat an `int` value as if it were a `bool` value. Don't try to circumvent type safety - nothing good can come of that. – Sander De Dycker Oct 20 '14 at 12:45
  • I got such result from third-party directory what I suspect happens is that class is created (on stack on heap it does not matter) and some fields are uninitialized then at some point I get a bool field using getter and compare it to true. Is that still UB? – Trismegistos Oct 20 '14 at 13:04
  • @Trismegistos : I think you need to take some time to figure out what the real question is that you want to ask. You seem to keep adding more info that significantly changes the question, which makes it very hard for us to keep up. Once you figured out what it is you want to ask, you can ask it as a new question. – Sander De Dycker Oct 20 '14 at 13:09
0
int a = 216;
bool* v = (bool*)((void*)&a);
std::cout << (*v == true) << endl;

a = 216 = 128+64+16+8 = 00000...11011000

*v = 1000 and if we print it , it shows true...

But true=0001 and it is not satisfy *v==true

Of course it is kinda guess after my experiments...

Thanks to you after that i always use something!=false instead of something== true...

or something==false instead of something!=true...

oknsnl
  • 351
  • 1
  • 11