C++ Logo

std-proposals

Advanced search

Re: [std-proposals] uintfuncptr_t (and mandatory uintptr_t)

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Wed, 2 Jul 2025 18:32:18 +0200
We went through on this mailing list that there is no guarantee that increasing a pointer by 1 also increases its int representation by 1.   Why do you want to store, pass or interpret a pointer as an integer? -----Ursprüngliche Nachricht----- Von:Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Mi 02.07.2025 17:34 Betreff:[std-proposals] uintfuncptr_t (and mandatory uintptr_t) An:std-proposals <std-proposals_at_[hidden]>; CC:Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>; First let's talk about uintfuncptr_t. The Standard says that the address of any non-member function can be safely cast to:    void(*)(void) and then back to the original function pointer type without any loss of information. So we already have a 'unified' function pointer type. There should be an integer type corresponding to this, and it should be std::uintfuncptr_t. So that's code memory dealt with. Moving onto data memory now . . . which by the way might need bigger or smaller pointers than code memory (e.g. Harvard Architecture). Let's talk about uintptr_t, and about why it's optional for compilers to provide. I've written assembler for around about five or six CPU instructions sets, and all these machines always treat a pointer just like an integer. For example on 64-Bit x86 machines, if you want to increment an integer, it will be:    add rax, 1 Similarly if you want to increment a pointer by one byte, it's:    add rax, 1 And so if the compiler can provide a " char * " type of suitable width to hold a memory address, then it can provide an integer type of the same width. No rocket science here. I've been trying to find examples of where this might not be possible, and I keep getting pointed to x86 Real Mode. It turns out that in the 1980's, you could use the Turbo C compiler to make pointers as follows:    char near *p;    char far *p; The former was 2 bytes, and it was just an offset into an unknown segment. The latter was 4 bytes, and contained both the segment address and the offset. In a setup like this, where a pointer can be modified with further qualifiers such as "near" and "far", I think there should be corresponding integer types:    std::uintptr_near_t      ( sizeof == 2 )    std::uintptr_far_t          ( sizeof == 4 ) And I think that 'std::uintptr_t' should be a typedef for whichever one is the default when you do:    char *p; And so in x86 Real Mode, the default is a near pointer and so uintptr_t should be 16-Bit. There's a simple universal implementation for these two types: #include <cstdint>                 // uintmax_t #include <type_traits>             // conditional namespace std {  typedef conditional_t< sizeof(unsigned) == sizeof(char*), unsigned,            conditional_t< sizeof(long unsigned) == sizeof(char*), long unsigned,              conditional_t< sizeof(long long unsigned) == sizeof(char*), long long unsigned,                conditional_t< sizeof(short unsigned) == sizeof(char*), short unsigned,                  conditional_t< sizeof(char unsigned) == sizeof(char*), char unsigned,                    conditional_t< sizeof(uintmax_t) == sizeof(char*), uintmax_t, void > > > > > > uintptr_tZ;  typedef conditional_t< sizeof(unsigned) == sizeof(void(*)(void)), unsigned,           conditional_t< sizeof(long unsigned) == sizeof(void(*)(void)), long unsigned,            conditional_t< sizeof(long long unsigned) == sizeof(void(*)(void)), long long unsigned,             conditional_t< sizeof(short unsigned) == sizeof(void(*)(void)), short unsigned,              conditional_t< sizeof(char unsigned) == sizeof(void(*)(void)), char unsigned,               conditional_t< sizeof(uintmax_t) == sizeof(void(*)(void)), uintmax_t, void > > > > > > uintfunctptr_tZ; } -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2025-07-02 16:41:20