Is a pointer with the right address and type still always a valid pointer since C++17?

Is this interpretation of this modification of the standard right or are there other rules that compensate the deletion of this cited sentence?

Yes, this interpretation is correct. A pointer past the end isn’t simply convertible to another pointer value that happens to point to that address.

The new [basic.compound]/3 says:

Every value of pointer type is one of the following:
(3.1)
a pointer to an object or function (the pointer is said to point to the object or function), or
(3.2)
a pointer past the end of an object ([expr.add]), or

Those are mutually exclusive. p1+1 is a pointer past the end, not a pointer to an object. p1+1 points to a hypothetical x[1] of a size-1 array at p1, not to p2. Those two objects are not pointer-interconvertible.

We also have the non-normative note:

[ Note: A pointer past the end of an object ([expr.add]) is not considered to point to an unrelated object of the object’s type that might be located at that address. […]

which clarifies the intent.


As T.C. points out in numerous comments (notably this one), this is really a special case of the problem that comes with trying to implement std::vector – which is that [v.data(), v.data() + v.size()) needs to be a valid range and yet vector doesn’t create an array object, so the only defined pointer arithmetic would be going from any given object in the vector to past-the-end of its hypothetical one-size array. Fore more resources, see CWG 2182, this std discussion, and two revisions of a paper on the subject: P0593R0 and P0593R1 (section 1.3 specifically).

Leave a Comment