In exploring pointer conversions to a string, intptr_t
and uintptr_t
like
void *p;
char sp[100];
snprintf(sp, sizeof sp, "%p, p);
intptr_t ip = (intptr_t) p;
I wondered how 2 pointers some_type *a; some_type *b;
and their equal-ness would transfer when converted.
Case 1: Two pointers point to the same place (object, offset within an object, 1-past, function, array) yet have different bit patterns, or are 2 null pointers that have different bit patterns. This case is hard to create on some platforms, if at all.
Certainly they compare equal as pointers (C11 §6.5.9 6). Yet as strings, intptr_t
or uintptr_t
, I expect them to be different, yet think being the same is OK.
Q1 Case 1 pointers convert (to string,
intptr_t
,uintptr_t
) the same or different - are both results compliant?
Case 2 (the common situation): All other pointer pair mixes but not of case 1: any of null, object, within object, 1-past object, function, ...
Q2 Case 2 pointers
a,b
: Musta == b
have the same result when converting to string,intptr_t
,uintptr_t
(using!strcmp()
,==
,==
)?
Use "%p"
to print a pointer might not be properly called "converting", but hopefully the idea is still conveyed.
Test code to exercise some possibilities.
void ptr_compare(void *pa, void *pb,
bool *pcmp, bool *mcmp, bool *scmp, bool *icmp, bool *ucmp) {
// pointer compare
*pcmp = pa == pb;
// memory compare
*mcmp = memcmp(&pa, &pb, sizeof pa) == 0;
// string compare
char sa[100];
snprintf(sa, sizeof sa, "%p", pa);
char sb[100];
snprintf(sb, sizeof sb, "%p", pb);
*scmp = !strcmp(sa, sb);
// signed compare
intptr_t ia = (intptr_t) pa;
intptr_t ib = (intptr_t) pb;
*icmp = ia == ib;
// unsigned compare
uintptr_t ua = (uintptr_t) pa;
uintptr_t ub = (uintptr_t) pb;
*ucmp = ua == ub;
}
void ptr_test(void *pa, void *pb) {
bool pcmp, mcmp, scmp, icmp, ucmp;
ptr_compare(pa, pb, &pcmp, &mcmp, &scmp, &icmp, &ucmp);
// If same bit pattern ...
if (mcmp) {
if (pcmp && scmp && icmp && ucmp) return;
// else different bit pattern ...
} else {
if (!pcmp && !scmp && !icmp && !ucmp) return;
}
// Something interesting !
printf("ptra:%p ptrb:%p --> pcmp:%d mcmp:%d scmp:%d icmp:%d ucmp:%d\n", pa,
pb, pcmp, mcmp, scmp, icmp, ucmp);
}
int main(void) {
char p[1];
void *ptrs[] = { 0, NULL, "123", "123", "456", p, p, main };
for (size_t ia = 0; ia < sizeof ptrs / sizeof ptrs[0]; ia++) {
for (size_t ib = 0; ib < sizeof ptrs / sizeof ptrs[0]; ib++) {
ptr_test(ptrs[ia], ptrs[ib]);
}
}
puts("Done");
return 0;
}
Results. On two tested platforms, I apparently cannot create "Something interesting !"
Done