Since ints and pointers are the same size in the ILP32
environment, a lot of code relies on this assumption. Pointers are often cast
to int or unsigned int for address arithmetic. Instead,
pointers could be cast to long because long and
pointers are the same size in both ILP32 and LP64 worlds. Rather than explicitly
using unsigned long, use uintptr_t because it expresses
the intent more closely and makes the code more portable, insulating it against
future changes. For example,
char *p; p = (char *) ((int)p & PAGEOFFSET);
produces the warning:
warning: conversion of pointer loses bits
Using the following code will produce the clean results:
char *p; p = (char *) ((uintptr_t)p & PAGEOFFSET);