On 11/07/2017 21:30, Andrey Semashev wrote:
You can cast both ways. The casted-from-char pointer can be used as long as the underlying object, in the C++ object model, matches the pointed type. In other words, this is fine:
std::size_t* p1 = new std::size_t[10]; char* p2 = reinterpret_cast< char* >(p1); std::size_t* p3 = reinterpret_cast< std::size_t* >(p2); assert(p1 == p3); p3[0] = 10; // ok
In Beast's case we (and compiler) cannot tell whether the pointers refer to std::size_t objects. For compiler that means it has to assume the objects exist and thus prevent any optimizations that would contradict it.
I'm not an expert, but I believe that strictly according to the standard it is UB to cast from a char* to any other pointer type, regardless. (It's also important to note that the standard only permits casting to "char*" -- not "unsigned char*" or "uint8_t*".) Having said that, as long as you are careful to only do so with POD types (or at least types that cannot have a vtable) and only when the alignment requirements of the type are met, then most compilers should probably let you get away with it, because it's far too useful functionality to ban outright. In the example above, since you're starting with a "real" type and then casting to char* and back you're guaranteed to meet the alignment requirements, so it should be reasonably safe. You can still run afoul of strict aliasing if you pass both pointers to other methods, however (but passing only one should be safe). Hopefully the compiler is smart enough to notice that they're aliased as long as you stay within the same method.