Can two implementation defined identical expressions give different results?
Yes. It's "implementation-defined" - all rules are up to implementation. An imaginary implementation may look like this:
int main() {
void *a = 0;
#pragma MYCOMPILER SHIFT_UINTPTR 0
printf("%d\n", (int)(uintptr_t)a); // prints 0
#pragma MYCOMPILER SHIFT_UINTPTR 5
printf("%d\n", (int)(uintptr_t)a); // prints 5
}
Still such an implementation would be insane on most platforms.
I could imagine a example: architecture that has to deal with memory in "banks". A compiler for that architecture uses a #pragma
switch to select the "bank" that is used for dereferencing pointers.
- (uintptr_t)NULL - (uintptr_t)NULL will the result always be zero?
Not necessarily.
- will x - x be always zero?
Yes. uintptr_t
is an unsigned integer type, it has to obey the laws of mathematics.
- Will x-y be always zero?
Not necessarily.
- Will x-y be always zero?
Not necessarily.
If not - why?
The result of conversion from void*
to uintptr_t
is implementation defined - the implementation may convert the pointer value to different uintptr_t
value each time, which would result in a non-zero difference between the values.
I could see a example: on some imaginary architecture pointers have 48-bits, while uintptr_t
has 64-bits. A compiler for such architecture just "doesn't care" what is in those 16 extra bits and when converting uintptr_t
to a pointer it uses only the 48-bits. When converting pointer to an uintrpt_t
compiler uses whatever garbage value was leftover in registers for the extra 16-bits, because it's fast to do that in that specific architecture and because they will never be used when converting back..