C++ Logo


Advanced search

Re: P1839 and the object representation of subobjects

From: Thiago Macieira <thiago_at_[hidden]>
Date: Tue, 21 Jul 2020 23:20:40 -0700
On Tuesday, 21 July 2020 16:38:40 PDT Jason McKesson via Std-Proposals wrote:
> 1: `byte_ptr + off`. Pointer arithmetic in C++ is based on arrays
> (which for a single object is treated as a 1-element array).
> `byte_ptr` does not point to an array of `char`, so pointer arithmetic
> is invalid.
> 2: The pointer resulting from `reinterpret_cast<C1*>` does not
> *actually* point to the subobject of type `C1` within the other
> object, even if the address `qoptr + off` is the address of that
> subobject.
> P1839R2 solves problem number 1, as stated by its wording:

> As for #2, `std::launder` from C++17 solves this problem:
> > [ptr.launder]/3
> > Requires: `p` represents the address `A` of a byte in memory. An
> > object X that is within its lifetime (6.8) and whose type is similar (7.5)
> > to T is located at the address `A`. All bytes of storage that would be
> > reachable through the result are reachable through `p` (see below).
> >
> > Returns: A value of type T* that points to `X`.
> There is an object of type `C1` at the address `byte_ptr + off`;
> therefore, `launder` retrieves a pointer to it.

Ok, I'm happy with that. The third piece of this puzzle is getting that
offset, which we need to either rely on offsetof (which is now conditionally
allowed on non-standard-layout types) or on a PMO.

Would it make sense to add this entire operation as a library function?

struct S
    int i, j;

  S s;
  back_to_object<&S::i>(&s.i) == &s
  back_to_object<&S::j>(&s.j) == &s

struct O
    virtual ~O();
    struct Empty {};
    [[no_unque_address]] Empty e;
    union {
        int k;

  O o;
  back_to_object<&S::e>(&o.e) == &o;
  back_to_object<&S::k>(&o.k) == &o;

Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel DPG Cloud Engineering

Received on 2020-07-22 01:24:06