C++ Logo

std-discussion

Advanced search

Re: C++17 accidentally made pointer arithmetic on type-punned pointers well-defined

From: Christopher Hallock <christopherhallock_at_[hidden]>
Date: Tue, 21 Mar 2023 10:15:29 -0400
> > When C++17 changed the abstract pointer model, it changed all non-null
> > type-punned pointers from "points to no object (but still denotes an
> > address)"
>
> Not sure that before C++17 we had "pointers to no object"
>

C++14 [basic.compound]/3 says:

> [...] A valid value of an object pointer type represents either the
> address of a byte in memory or a null pointer. If an object of type T is
> located at an address A, a pointer of type cv T* whose value is the address
> A is said to point to that object, regardless of how the value was
> obtained. [...]


I interpret this as having an implied "...otherwise, an object pointer does
not point to anything" at the end.


> to "points to an object (just not the one the pointer type
> > suggests)". In doing so, it accidentally made pointer arithmetic
> ([expr.add]
> > <https://timsong-cpp.github.io/cppwp/expr.add>) on type-punned pointers
> > well-defined (but unimplementable when sizeof(T) != sizeof(element) for a
> > T*).
> >
> > For example:
> > #include <iostream>
> > short* cast(long* p) { return reinterpret_cast<short*>(p); }
> > int main() {
> > long a[2];
> > // gcc says 0. Standard says 1.
> > std::cout << (cast(a) + 1 == (void*)(a + 1)) << "\n";
> > // gcc says 4 on x86-64. Standard says 1.
> > std::cout << (cast(a + 1) - cast(a)) << "\n";
> > }
>
> The standard says UB. https://timsong-cpp.github.io/cppwp/n4659/expr.add#6


 Ah, I missed that! There is no issue, then. Thank you.

Received on 2023-03-21 14:15:43