Question

According to strict aliasing rules:

struct B { virtual ~B() {} };
struct D : public B { };

D d;
char *c = reinterpret_cast<char*>(&d);

A char* to any object of different type is valid. But now the question is, will it point to the same address of &d? what is the guarantee made by C++ Standard that it will return the same address?

Was it helpful?

Solution

c and &d do indeed have the same value, and if you reinterpret-cast c back to a D* you get a valid pointer that you may dereference. Furthermore, you can treat c as (pointer to the first element of) an opaque array char[sizeof(D)] -- this is indeed the main purpose of casting pointers to char pointers: To allow (de)serialization (e.g. ofile.write(c, sizeof(D));), although you should generally only do this for primitive types (and arrays thereof), since the binary layout of of compound types is not generally specified in a portable fashion.

As @Oli rightly points out and would like me to reinforce, you should really never serialize compound types as a whole. The result will almost never be deserializable, since the implementation of polymorphic classes and padding between data fields is not specified and not accessible to you.

Note that reinterpret_cast<char*>(static_cast<B*>(&d)) may be treated as an opaque array char[sizeof(B)] by similar reasoning.

OTHER TIPS

Section 5.2.10, point 7 of the 2003 C++ Standard says:

A pointer to an object can be explicitly converted to a pointer to an object of different type. Except that converting an rvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

If by "same address" you mean "original pointer value," then this entry says "yes."

The intent is clear (and not something that needs to be debated):

reinterpret_cast never changes the value of an address, unless the target type cannot represent all address values (like a small integer type, on a pointer type with intrinsic alignment: f.ex. a pointer that can only represent even addresses, or pointers to object and pointers to functions cannot be mixed...).

The wording of the standard fails to capture that, but that doesn't mean there is a real practical issue here.

char *c = reinterpret_cast<char*>(&d);

c will point to the first byte of d, always.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top