C++ reinterpret cast

C++ reinterpret cast is one of the most dangerous and notorious type of casting in the entire C++. Unlike the other method, reinterpret_cast treat data as a bit pattern that can be casted from one type to another type. It conveniently cast any pointer type to another type without caring the consequences. Consider the code below.

char c=’C’ , *cpt=&c
int *i=reinterpret_cast< int* > (cpt) ; //char* casted to int*

cout<< *i ; //undefine value 

Accessing the value using ‘*i’ will give you an undefined value, why?

One of the reasons is char* points to char value which is just 1 byte large but the int* pointer is meant to point to int type which is 4 bytes large. When ‘cpt’ is casted to int* type ‘*i’ still needs to point to 4 bytes memory. But cpt points to only 1 byte memory.

Now the question is, where are the extra 3 bytes going to come from? It is simple, the compiler had to just take 3 bytes from somewhere and bam! put it next to the 1 byte of the original ‘c’ memory and make it a total of 4 bytes. This sure is not a reasonable act on the part of the compiler but don’t blame the compiler because reinterpret_cast had force the compiler to do so. Blame the reinterpret_cast instead .

That being said it’s not like there is no solution for this, in fact, there is and a simple one. Before we use any pointer which the reinterpret_cast result is assigned to, we will cast it back to its original type. After this, we can safely use the pointer to access the value or do anything.

cout<< *(reinterpret_cast< char* >(i) );

Output,

C

which is the original character pointed by cpt.


General discussion on reinterpret_cast

The reinterpret_cast works only on pointers and references. It does not work on variables. So the basic function of reinterpret_cast is to cast from one pointer type to another pointer type. It can also cast a void pointer to any type which is another notorious act of the reinterpret_cast; static_cast also exhibits this behaviour.

int i=908;
float f=reinterpret_cast<int>(i) ; //error!!

void *vd=&i ;
float *fpt=reinterpret_cast<float*>(vd);

cout<< *fpt ; //undefine output
//Here again we must cast back fpt to int type to access the original value.

int* ipt=reinterpret_cast<int>(fpt) ;

cout<< *ipt ; //gives 908

Structure and class pointer

Another notorious act of reinterpret_cast is it can cast a pointer of one structure to another structure. This certainly doesn’t make any sense. Consider the code below.

struct A { } ;

struct B{ } ;

A a ,*apt=&a ;

B *b=reinterpret_cast<B>(apt) ;

Does it make sense to you here casting ‘a’ to B type, I don’t think so.


In-depth discussion on reinterpret_cast

As stated before reinterpret_cast treat any pointers as just a raw bit pattern, it is not concerned about the type the bits represent on the surface. All it does is interpret the raw bits of one type to another type. To show you how reinterpret_cast interpret the raw bits pattern, consider the example below.

nt i=890 ,*ipt=&i ;

char *cpt=reinterpret_cast<char*> (ipt) ;

cout<< *cpt ;

The output is

C

why? let’s look at the raw bits of 890 which is,

Now reinterpret_cast will try to interpret this binary digit to char type. Since char type size is only 1 byte, out of the 4 bytes, only 1 byte (the 8 leftmost bits) is considered, which is 01111010. This binary digit is the same as the binary digit of the value 122. Since the cpt type is char it will try to interpret this binary digit in character. If we look at the ASCII chart, the character corresponding to the value 122 is ‘C’. So ‘C’ is printed as the output value.

Now this means the remaining 3 bytes are neglected when reinterpret_cast is performed, but note here the 3 bytes is still part of the variable ‘i’, so it is still a valid memory.

Here you can see that the reinterpret_cast simply takes the underlying bits and cast it to another type with no due respect of the type.