|
Boost : |
Subject: Re: [boost] [beast] Formal review
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-07-11 23:33:10
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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk