C++ Logo

std-proposals

Advanced search

Re: Allowing access to object representations

From: Brian Bi <bbi5291_at_[hidden]>
Date: Thu, 1 Aug 2019 16:42:50 -0500
On Mon, Jul 29, 2019 at 3:25 PM Timur Doumler via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> I am probably missing something here, but can't we solve this in C++20 by
> doing a std::bit_cast<std::byte[sizeof(T)]>?
>

I'm not sure if `std::bit_cast` can perform a cast to an array. The wording
does not seem to allow it, since it says that the function returns "an
object of type To", but an array cannot be returned by value. I imagine
that at some point, someone will notice this and fix it by forbidding `To`
from being an array. You could perhaps try casting to
`std::array<std::byte, sizeof(T)>` or to `struct { std::byte a[sizeof(T)]
}`, but this is not really satisfactory because there is no portable way to
force the compiler to not add padding at the end of the struct.

You can still access the underlying bytes of an object by `memcpy`ing them
into an array and, if you so choose, modifying the array and `memcpy`ing
the bytes back into the original object, but this obviously has issues too.
For example: `memcpy` is not guaranteed to be available on a freestanding
implementation, compilers may have trouble optimizing this pattern, and
above all, the type of code that the OP wants to make well-defined, e.g.,

using T = unsigned char*;int a = 0;
T b = reinterpret_cast<T>(&a);// Pointer value unchanged, still//
points to the int object
T c = ++b;// UB, expression type differs// from element type


is code that everyone knows SHOULD be well defined. CWG stated as such in
response to CWG 1314. Then the C++17 memory model changes came along and
threw all that into doubt. This unfortunate state of affairs should be
fixed.

Note also that the C++17 memory model changes (as far as I can see) broke
typical usage of `offsetof`
<https://stackoverflow.com/questions/47498585/is-adding-to-a-char-pointer-ub-when-it-doesnt-actually-point-to-a-char-arr>,
and there is no way to solve this problem with `std::bit_cast`. (Usually
`offsetof` is used when you have a pointer to a member subobject of some
object `x` and you want to obtain a pointer to `x`.) The OP's proposal
would fix this. I have no opinion on whether the OP's proposal is the best
way to fix this, but some solution is clearly needed.

If I may be political for just a bit longer: people are not going to stop
writing code like the above. I am sure most of us remember how in the early
2000s most C++ programmers did not care whether their code had UB but were
instead adhering to a sort of unofficial standard where e.g., something
like dereferencing a null pointer would be illegal, but violating strict
aliasing is A-OK. If code like the above remains UB according to the
standard then people will ignore the fact that it's UB and the hard-won
legitimacy of the ISO C++ Standard will be eroded. Do we really want to go
back in that direction?


>
> Also, it would be very helpful if your paper provided a full code example
> showing before/after (i.e. something that is UB today but behaves
> differently with the changes you propose).
>
> Cheers,
> Timur
>
> > On 29 Jul 2019, at 02:17, sdkrystian via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >
> > Hi all,
> >
> > I've recently started work on a proposal to allow obtaining a pointer to
> the object representation of an object, and I want to get a sense of what
> you guys think. Linked in this email is my current draft, if you have time,
> take a look!
> >
> >
> https://github.com/18/accessing-object-representations/blob/master/paper.md
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > http://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> http://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>


-- 
*Brian Bi*

Received on 2019-08-01 16:45:02