6 Basics [basic]

6.6 Memory and objects [basic.memobj]

6.6.4 Storage duration [basic.stc]

6.6.4.4 Dynamic storage duration [basic.stc.dynamic]

6.6.4.4.3 Safely-derived pointers [basic.stc.dynamic.safety]

A traceable pointer object is
A pointer value is a safely-derived pointer to a dynamic object only if it has an object pointer type and it is one of the following:
  • the value returned by a call to the C++ standard library implementation of ::operator new(std::​size_­t) or ::operator new(std::size_­t, std::align_­val_­t);37
  • the result of taking the address of an object (or one of its subobjects) designated by an lvalue resulting from indirection through a safely-derived pointer value;
  • the result of well-defined pointer arithmetic ([expr.add]) using a safely-derived pointer value;
  • the result of a well-defined pointer conversion ([conv.ptr], [expr.cast]) of a safely-derived pointer value;
  • the result of a reinterpret_­cast of a safely-derived pointer value;
  • the result of a reinterpret_­cast of an integer representation of a safely-derived pointer value;
  • the value of an object whose value was copied from a traceable pointer object, where at the time of the copy the source object contained a copy of a safely-derived pointer value.
An integer value is an integer representation of a safely-derived pointer only if its type is at least as large as std::intptr_­t and it is one of the following:
  • the result of a reinterpret_­cast of a safely-derived pointer value;
  • the result of a valid conversion of an integer representation of a safely-derived pointer value;
  • the value of an object whose value was copied from a traceable pointer object, where at the time of the copy the source object contained an integer representation of a safely-derived pointer value;
  • the result of an additive or bitwise operation, one of whose operands is an integer representation of a safely-derived pointer value P, if that result converted by reinterpret_­cast<void*> would compare equal to a safely-derived pointer computable from reinterpret_­cast<void*>(P).
An implementation may have relaxed pointer safety, in which case the validity of a pointer value does not depend on whether it is a safely-derived pointer value.
Alternatively, an implementation may have strict pointer safety, in which case a pointer value referring to an object with dynamic storage duration that is not a safely-derived pointer value is an invalid pointer value unless the referenced complete object has previously been declared reachable ([util.dynamic.safety]).
[Note
:
The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined, see [basic.stc].
This is true even if the unsafely-derived pointer value might compare equal to some safely-derived pointer value.
end note
]
It is implementation-defined whether an implementation has relaxed or strict pointer safety.
This subclause does not impose restrictions on indirection through pointers to memory not allocated by ::operator new.
This maintains the ability of many C++ implementations to use binary libraries and components written in other languages.
In particular, this applies to C binaries, because indirection through pointers to memory allocated by std::malloc is not restricted.