C++ Logo


Advanced search

Re: reading values as bytes without memcpu, from enum unsigned char?

From: Roman Babinicz <rb_at_[hidden]>
Date: Fri, 7 Aug 2020 18:06:32 +0200
On 07/08/2020 17:43, language.lawyer--- via Std-Discussion wrote:
> On 07/08/2020 18:16, Jason McKesson via Std-Discussion wrote:
>> On Fri, Aug 7, 2020 at 10:06 AM <language.lawyer_at_[hidden]> wrote:
>>> On 07/08/2020 16:51, Jason McKesson via Std-Discussion wrote:
>>>> The cast is legal. Accessing the `unsigned char` at that address is
>>>> legal.
>>> You can't access `unsigned char` objects, `reinterpret_cast<unsigned
>>> char*>(buf)` points to the object of `mybyte` type.
>> According to [basic.lval]/8.8, I can:
>>> If a program attempts to access the stored value of an object through
>>> a glvalue of other than one of the
>> following types the behavior is undefined:
>>> ...
>>> a char, unsigned char, or std::byte type.
>> So it doesn't matter what `T1` is; you can access that byte as an
>> `unsigned char`. And indeed, if you could get a pointer to *any* byte
>> within `T1`, you can access it as an `unsigned char`.
>> It's getting a pointer to those bytes that is the problem.
> That is what was meant by "you can't access `unsigned char` objects".
> You can't get a pointer to them.
>>> But accessing an object of `mybyte` type through a glvalue of
>>> `unsigned char` type is indeed legal, because an enumeration with a
>>> fixed underlying type has the same values as the underlying type.
>> Actually, that's not true. I mean, it is true that the value
>> representations are the same, but that doesn't mean you can access
>> them through different types. [basic.lval] has no special provisions
>> for an enum and its underlying type.
> I was speaking exactly about the case of `enum mybyte : unsigned char`.
> If there were no rule explicitly saying
>> For an enumeration whose underlying type is fixed, the values of the
>> enumeration are the values of the underlying type.
> accessing an object of `mybyte` type through an `unsigned char` glvalue
> would be UB because of [expr.pre]/4, even though [basic.lval] "allows"
> such access.
> Your
>> The cast is legal. Accessing the `unsigned char` at that address is
>> legal. But without P1839, actually doing the pointer arithmetic needed
>> to access more than one such byte is not.
> sounds like that now, without P1839, there is some "access to one byte",
> which is not the case.

I think we should have a DR about the rules being unclear, and there
should be such example with such explanations added there, regarding
this access.

For C++14 and higher standards.

Any thoughts on making this happen?

As a separate note, allowing the exception with enum of underlying type,
would allow people to write custom std::byte in C++14 (possible also in
other places of standard where std::byte is mentioned as blessed type)

Received on 2020-08-07 11:10:26