I have a question regarding using intptr_t
vs. long int
. I've observed that incrementing memory addresses (e.g. via manual pointer arithmetic) differs by data type. For instance incrementing a char pointer adds 1 to the memory address, whereas incrementing an int pointer adds 4, 8 for a double, 16 for a long double, etc…
At first I did something like this:
char myChar, *pChar;
float myFloat, *pFloat;
pChar = &myChar;
pFloat = &myFloat;
printf( "pChar: %d\n", ( int )pChar );
printf( "pFloat: %d\n", ( int )pFloat );
pChar++;
pFloat++;
printf( "and then after incrementing,:\n\n" );
printf( "pChar: %d\n", (int)pChar );
printf( "pFloat: %d\n", (int)pFloat );
which compiled and executed just fine, but XCode gave me warnings for my typecasting: "Cast from pointer to integer of different size."
After some googling and binging (is the latter a word yet?), I saw some people recommend using intptr_t
:
#include <stdint.h>
...
printf( "pChar: %ld\n", ( intptr_t )pChar );
printf( "pFloat: %ld\n", ( intptr_t )pFloat );
which indeed resolves the errors. So, I thought, from now on, I should use intptr_t
for typecasting pointers… But then after some fidgeting, I found that I could solve the problem by just replacing int
with long int
:
printf( "pChar: %ld\n", ( long int )pChar );
printf( "pFloat: %ld\n", ( long int )pFloat );
So my question is, why is intptr_t
useful, and when should it used? It seems superfluous in this instance. Clearly, the memory addresses for myChar
and myFloat
were just too big to fit in an int
… so typecasting them to long int
s solved the problem.
Is it that sometimes memory addresses are too big for long int
as well? Now that I think about it, I guess that's possible if you have > 4GB of RAM, in which case memory addresses could exceed 232 – 1 (max value for unsigned long int
s…) but C was created long before that was imaginable, right? Or were they that prescient?
Thanks!
Best Answer
intptr_t
is a new invention, created after 64-bit and even 128-bit memory addresses were imagined.If you ever need to cast a pointer into an integer type, always use
intptr_t
. Doing anything else will cause unnecessary problems for people who need to port your code in the future.It took a long time to iron out all of the bugs with this in programs like Mozilla/Firefox when people wanted to compile it on 64-bit Linux.