Wednesday, 3 February 2010

reinterpret_cast in C++

From the Cpp Reference:

Syntax: TYPE reinterpret_cast (object);

The reinterpret_cast operator changes one data type into another. It should be used to cast between incompatible pointer types.

Suppose we have two variables, int a and char b

In C programming we can covert from b to a by:
a = (int)b;

In C++, the proper way to do this would be by using cast. One way is to use:
a = reinterpret_cast(b);

Most of the time reinterpret_cast is not required in the programs and can often be very dangerous. The following is from MSDN:

The reinterpret_cast operator also allows any integral type to be converted into any pointer type and vice versa. Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.

The reinterpret_cast operator can be used for conversions such as char* to int*, or One_class* to Unrelated_class*, which are inherently unsafe.

The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, nonportable.

The reinterpret_cast operator cannot cast away the const, volatile, or __unaligned attributes. See const_cast Operator for information on removing these attributes.

The reinterpret_cast operator converts a null pointer value to the null pointer value of the destination type.

One practical use of reinterpret_cast is in a hash function, which maps a value to an index in such a way that two distinct values rarely end up with the same index.

Instead of reinterpret_cast people generally prefer static_cast

Lets look at an example of reinterpret_cast:





//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

int
a = 22;
float
b = (float)33.3333;

cout<<"1. a = "<< a <<" b = "<< b <<endl;

a = (int)b; //Old C programming way
cout<<"2. a = "<< a <<" b = "<< b <<endl;

//Wont work in this case because floating point format is different
a = reinterpret_cast<int&>(b);
cout<<"3. a = "<< a <<" b = "<< b <<endl;

a = static_cast<int>(b); //Correct approach
cout<<"4. a = "<< a <<" b = "<< b <<endl;

char
c;
//Convert int to char
c = reinterpret_cast<char&>(a);
cout<<"5. c = "<< (int)c <<" a = "<< a <<endl;

//Dangerous to convert from char to int
a = reinterpret_cast<int&>(c);
cout<<"6. c = "<< (int)c <<" a = "<< a <<endl;

//What we actually wanted was just the last 8 bits so...
a = a & 0x000000FF; //00 = 8 bits
cout<<"7. c = "<< (int)c <<" a = "<< a <<endl;

return
0;
}






The output is as follows:

4 comments:

  1. The output of the following program should be 0. But, thats not happening in this case. Pls correct me if im wrong

    int main()
    {
    bool pi = 0;
    bool * p = π
    int * b = reinterpret_cast (p);

    cout << *b;
    return 0;

    }

    ReplyDelete
  2. Ok, blogger comment posting messes up the program so I see a pi sign in your comment above.

    Since boolean only needs 1 byte and integer needs 4 bytes, the 3 MSB bytes will be uninitialised.

    In debug mode this is generally CCCCCC.

    ReplyDelete
  3. great post. That's what i was looking for.

    ReplyDelete