Issue 1125: intptr_t and uintptr_t questions

Authors: Jay Ghiron
Date: 2026-10-29
Submitted against: C23
Status: Open

This issue is about the following:

The following type designates a signed integer type, other than a bit-precise integer type, with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

intptr_t

The following type designates an unsigned integer type, other than a bit-precise integer type, with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

uintptr_t

These types are optional.

(C23 7.22.2.5 "Integer types capable of holding object pointers" paragraph 1.)

For the purposes of this issue, assume that the implementation supports both intptr_t and uintptr_t. Issues relating to provenance will not be discussed. If N3914 is accepted, all questions except the last would also be relevant for the types intfuncptr_t and uintfuncptr_t when considering _Any_func* instead of void* and function pointers instead of object pointers.

Question 1

For the purposes of this paragraph, what is a valid pointer? Should null be considered a valid pointer here? For all further questions, assume that all pointers provided as arguments in the examples are valid for whatever definition is chosen.

Question 2

Since this paragraph specifically considers void*, does this guarantee not extend to other object pointer types? For example:

#include<stdint.h>
const void*foo(const void*p){
return(const void*)(uintptr_t)p;
}
char*bar(int*q){
return(char*)(uintptr_t)q;
}

Can an implementation give different results for these functions when compared to casting between pointer types directly?

Question 3

Can multiple conversions of the same pointer to intptr_t or multiple conversions of the same pointer to uintptr_t result in different values? For example:

#include<stdint.h>
int baz(void*r){
return(uintptr_t)r==(uintptr_t)r;
}

Can this function ever return zero? One example of where it would be useful to guarantee equivalent results is xor linked lists, however niche those are. If multiple conversions to uintptr_t can result in different values then iteration has to keep uintptr_t values rather than pointers, because pointers could not reliably turn back into uintptr_t values that could be used for iteration.

Question 4

The descriptions of intptr_t and uintptr_t are done independently, was it intended to not provide any guarantees when converting between them? For example:

#include<stdint.h>
void*qux(void*s){
return(void*)(uintptr_t)(intptr_t)s;
}

Was it intended that this may be undefined?

Question 5

There does not appear to be anything that specifically prohibits converting an intptr_t value to void* or a uintptr_t value to void* when in either case it would result in a pointer to or one past an object that has had its lifetime end. Can it be inferred from C23 6.2.4 that the result is undefined assuming the integer value was not reused, or can the resulting pointer still be used in some limited contexts?