C++ Logo

std-discussion

Advanced search

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

From: Christopher Hallock <christopherhallock_at_[hidden]>
Date: Tue, 21 Mar 2023 00:27:46 -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)" 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";
}

Received on 2023-03-21 04:28:01