void *oldptr = malloc(73);
uintptr_t savedptr = (uintptr_t)oldptr;
void *newptr = realloc(oldptr, 42);
if (savedptr == (uintptr_t)newptr) {
// not changed
}I'm not sure it's also OK, because the memcmp suggestion you are replying to seems a bit suspect.
There's still the problem that comparing the uintptr_t's is not guaranteed to yield the same result as the pointers they were cast from. But that's merely implementation-specific behaviour, not undefined.
(An unsigned type can only have trap patterns if it has padding bits. Every combination of the value bits is a valid value according to the pure binary encoding.)
int *oldptr = (int *)malloc(42);
int *newptr = (int *)realloc(oldptr, 73);
if (oldptr == newptr) {
newptr[70] = 10; // ok because the "object" newptr can contain 73 ints
oldptr[70] = 10; // SIGABRT here because the "object" oldptr can only contain 42 ints even though the memory block oldptr points to can hold 73
} void *ptr = malloc(73);
void *old = ptr;
void *ptr = realloc(ptr, 42);
bool realloced = old != ptr;Not comparing the values is the point. Your code uses the pointer that was passed to realloc, and that is undefined behavior according to ISO C.
The game you're playing with the identifiers is pointless; there is no difference between what you're trying to do and just:
void *oldptr = malloc(73);
void *newptr = realloc(oldptr, 42);
bool realloced = oldptr != newptr; // undefined behavior
That's what the article is referring to, and that I'm specifically addressing with the memcmp. Accessing the pointer as an array of bytes doesn't use its value as a pointer. Bytes cannot be indeterminate; they are not allowed to have trap representations.(There could be a false negative: the address didn't change, but the pointer bit pattern did. On 64 bit systems, the C library could easily put a tag into the upper bits of the pointer, and have realloc change the tag even if the address is the same.)
The problem described in the article is that the compiler generated a false negative even when the pointer didn't change, due to the undefined behavior. The idea is something like that since oldptr was passed to realloc, it is garbage. The newptr is good, and we need not compare garbage to non-garbage; we can just declare them to be unequal.
That's what you might get if your follow your advice of "compare the values, so that the compiler knows about it".