C++ Logo

std-discussion

Advanced search

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

From: language.lawyer_at <language.lawyer_at_[hidden]>
Date: Tue, 21 Mar 2023 11:08:10 +0500
> 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"

> 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

Received on 2023-03-21 06:08:16