|
Boost : |
Subject: Re: [boost] [beast] Formal review
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2017-07-11 09:30:14
On 07/11/17 03:34, Phil Endecott via Boost wrote:
> Andrey Semashev wrote:
>>
>> C++ allows chars and unsigned chars (which std::uint8_t presumably is)
>> to alias other types
>
> My understanding is that you can reinterpret_cast FROM other types TO
> chars, but not FROM chars TO other types.
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.
The cases where the compiler cannot tell whether the object exists or
not are kind of a grey area in the standard because it doesn't clarify
that, but in practice it must work. Otherwise it would be the end of the
world because we use C APIs everywhere and C cannot create a C++ object
currently. There were multiple discussions about this on the std mailing
lists.
Note that when you _can_ tell there is an object, and the type of the
object is different from the pointee then this is still UB:
double* p1 = new double[10];
char* p2 = reinterpret_cast< char* >(p1);
std::size_t* p3 = reinterpret_cast< std::size_t* >(p2);
p3[0] = 10; // UB
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk