C++ Logo


Advanced search

Re: [SG14] [isocpp-parallel] (SC22WG14.16350) Rough notes from SC22 WG21 SG14 meeting on pointer lifetime-end zap

From: Hans Boehm <boehm_at_[hidden]>
Date: Thu, 2 May 2019 21:16:37 -0700
On Thu, May 2, 2019 at 1:58 AM Niall Douglas via cl-C-memory-object-model <
cl-c-memory-object-model_at_[hidden]> wrote:
> On 02/05/2019 07:50, Jens Maurer via SG14 wrote:
> >
> > So, we seem to be in violent agreement that the current rule of
> > invalidating a pointer value system-wide once the heap storage
> > it points to is freed is not a good rule: People don't actually
> > observe it when programming, and it makes certain algorithms near-
> > impossible to implement (uintptr_t is not available unconditionally).
> Why are pointers to heap storage any different to pointers to any storage?
> I think we need pointer values to gain a new treatment during pointed-at
> invalidation: they get converted to some bunch of stable bits which are
> not indeterminate, but are also not dereferenceable. The bunch of stable
> bits chosen may not be the bits for a valid pointer value, but should
> still uniquely identify the storage it used to point to.
> The really hard question is how an invalidated pointer with provenance A
> ought to be comparable to an invalidated pointer with provenance B? So,
> in code:
> T *a = new T;
> delete a;
> T *b = new T;
> // Everybody agrees the compiler can assume this is always true
> assert(a != b);
I'm not at all sure this is right. The compiler can definitely assume that
*a and *b do not alias; falsifying that would involve dereferences which
would result in undefined behavior. And disallowing that assumption would
slow down code. But that's not really exposed to the user, and not the same
thing as claiming a!=b is true. I would prefer that the compiler not
automatically claim that a != b. The only cases in which I would actually
write code like that is when I'm debugging a memory corruption issue, and
actually want to know whether b reused a's address. Simplifying this to
true doesn't seem helpful to me, and it doesn't appear to me that it is
likely to result in appreciably better code.

If the compiler includes version numbers in the pointers, so that there
can't be dangling pointer dereference issues, and the bit patterns actually
are different, then I'm fine with simplifying a != b to true.

> delete b;
> // What happens here? Can the compiler assume this is true, or
> // false, or is the compiler required to always do a runtime check?
> assert(a != b);
> The safest approach is to require runtime checking for all pointer
> comparisons involving invalidated pointer values.
> Niall

Received on 2019-05-02 23:18:28