Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

char* conversion and aliasing rules

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?

like image 292
user1086635 Avatar asked Dec 18 '11 22:12

user1086635


2 Answers

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.

like image 172
Kerrek SB Avatar answered Nov 07 '22 19:11

Kerrek SB


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."

like image 2
Gnawme Avatar answered Nov 07 '22 18:11

Gnawme