views:

183

answers:

2

According to C++ Standard, a reinterpret_cast of a pointer T* to some other type pointer Q* can change or not change the pointer value depending on implementation.

I'm very interested - it there any real example of a C++ implementation where casting a pointer to some other pointer type with reinterpret_cast changes the pointer? What and why is changed there?

+4  A: 

Note that when the standard states that it can or cannot possibly do something, it does not mean that there is any current implementation that has that behavior, only that they could.

The closest that I can think of is an architecture where type alignment was required by the hardware, and an implementation that decided to correct alignment if needed. Something like:

aligned8 var;
aligned1 *p = reinterpret_cast<aligned1*>(&var);
aligned1 *q = p + 1; // assuming aligned 1 size is not multiple of 8
aligned8 *a = reinterpret_cast<aligned8*>(q); // [1]

There could be a requirement that for a to be a valid pointer it has to address a memory position multiple of 8, while the argument q with lesser alignment requirements could point to any memory address.

David Rodríguez - dribeas
+2  A: 
class A1 { int a1; };
class A2 { int a2; };

class B: public A1, public A2 { };

#define DBG(val)  cout << #val << ": " << val << endl

// test code
B b;
DBG(&b);                                           // prints 0x42

void *p_blank = &b;
DBG(p_blank);                                      // prints 0x42
A2 *p_a2 = &b; 
DBG(p_a2);                                         // prints 0x46
void *p_reinterpreted = reinterpret_cast<A2*>(&b);
DBG(p_reinterpreted);                              // prints 0x42
A2 *p_reinterpreted2 = reinterpret_cast<A2*>(&b);
DBG(p_reinterpreted2);                             // prints 0x42

A2 *p_a2 = &b means give me the pointer to an A2 object within the B object. reinterpret_cast<A2*>(&b) means give me the pointer to b and treat it as an A2 pointer. The result of this reinterpret_cast has the type 'pointer to A2', therefore it produces no warning when assigned to a void* variable (or to a A2* variable).

`A2* p_a2 = ` surprises me...
akira
In your example the `reinterpret_cast` does not change the value at all... you're off I am afraid.
Matthieu M.
In `A2 *p_a2 = ` you use implicit conversion that is equivalent to `static_cast`, not `reinterpret_cast`.
sharptooth
It seems I didn't understand the question correctly.I understood that you search for a case where reinterpret_cast<> returns a different value than a blank 'address of' operator. I didn't find a clause in the C++ standard which allows that reinterpret_cast<T*> differs from reinterpret_cast<F*>.
@akira: When you make an implicit upcast (or `static_cast`) to a base pointer, the returned pointer is the address of that base's subclass within the object. When you do that with the first base, the addresses coincide. If there is multiple inheritance, upcasting to all but the first base (assuming that the first base class is not empty) will produce pointers that are offset. In this particular example, `A1` class takes exactly 4 bytes.
David Rodríguez - dribeas