Is it well-defined to make a cast from a pointer to an int and back?
Like:
typedef struct
{
int whatever;
} S;
int main(void)
{
S* s = malloc(sizeof(S));
int i = (int) s;
S* t = (S*) i;
t.whatever = 42;
etc.
}
On two conditions:
- that the cast from pointer to int doesn't lose any information, i.e.,
that an int is wide enough to hold all pointer values;
- that the pointer is cast to int and then back to the _same_ pointer
type;
AFAICT this is well-defined.
The second condition, only you yourself have any influence over. Just
don't convert a pointer to an integer and then to a different pointer
type. In this case, you're OK.
The first depends on the platform. If you have C99, you may be able to
use (u)intptr_t, which are integer types (not necessarily ints) capable
of holding any void * value safely. Declare i as intptr_t, and cast s to
void * before assigning it to i, and back the other way 'round, too:
intptr i = (int)(void *)s;.
S *t = (void *)i;
You don't need a cast to (S *) in the second line, since a void * will
be automatically and correctly converted to any object pointer type.
Unfortunately, these types are optional, and they don't exist in C89 at
all. If it's unavailable to you, you may just have to resort to using
unsigned long (or unsigned long long) and hoping that that's large and
well-aligned enough. It probably is, but it's not guaranteed. If you
have intptr_t, use it.
Richard