C++ Logo

std-proposals

Advanced search

Re: Allowing access to object representations

From: Brian Bi <bbi5291_at_[hidden]>
Date: Tue, 20 Aug 2019 19:38:34 -0400
On Tue, Aug 20, 2019 at 8:24 AM Timur Doumler <cpp_at_[hidden]> wrote:

> Hi Brian,
>
> > On 19 Aug 2019, at 23:23, Brian Bi via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> > Exactly - that means it's still undefined. As I said in one of my
> earlier messages, it is undesirable to change the standard in a way that
> breaks lots of code which people will then not rewrite, as this erodes the
> legitimacy of the standard (and leaves users uncertain about what might get
> trampled by their compiler optimizers the next time they update.) Yet
> that's exactly what happened in C++17, and we should fix that.
>
> Could you please explain exactly what change in C++17 you are referring to
> here?
>

The change to the object/memory model made by P0137. At the very least,
this breaks any code similar to the following:

int x = 12345;
auto p = reinterpret_cast<unsigned char*>(x);
for (int i = 0; i < sizeof(x); i++) {
    std::cout << p[i] << '\n';
}

In Core Issue 1314, CWG said that "the current wording":

The *object representation* of an object of type T is the sequence of
*N* unsigned
> char objects taken up by the object of type T, where *N* equals sizeof(T).
>

made it "sufficiently clear" that such code was well-defined. (August,
2011) The reinterpret_cast produces a pointer to the first byte of the
object representation of x. The issue of whether the pointer arithmetic is
valid was raised again in Core Issue 1701 - pointer arithmetic requires an
array, and a "sequence" is not unambiguously an array. Core Issue 1701 is
still unresolved. However, I feel confident saying that in August 2011, the
code above was "supposed" to be well-defined, though a small number of
people disagree. CWG simply had not realized at that point that the wording
was defective. In 2013, when issue 1701 was raised, they realized the
wording was defective.

But thanks to P0137, the above code is no longer well-defined even if you
want to stretch the reading of the wording, because the result of the
reinterpret_cast no longer points to the first byte of the object
representation; it just points to the original int object. The pointer
arithmetic cannot possibly do the right thing, and according to the plain
wording, neither can the lvalue-to-rvalue conversions.


>
> Thanks,
> Timur
>


-- 
*Brian Bi*

Received on 2019-08-20 18:40:50