Ben Clifford
Ben Clifford

Reputation: 1418

Cast pointer to larger int

I have a pointer. On a 32-bit system it's 32 bits. On a 64-bit system it's 64 bits.

I have a long long integer field used as an identifier, and sometimes I want to use the pointer value in there. (I never cast back to a pointer - once I've cast it to the integer field, I only ever compare it for equality).

On both 32-bit and 64-bit systems, it seems safe to do this. (On larger pointered systems not so). Is that true?

And then, is there a way to make GCC not give the following warning only when building on platforms where this is safe (which is, at the moment, all target platforms)?

error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]

Upvotes: 8

Views: 5306

Answers (2)

md5
md5

Reputation: 23727

According to the standard, there is no guarantee that a pointer fits in an integer type. In practical, otherwise, on mostly personnal computers, there exists several memory models. You can see pointer and integer types have not always the same size (even on "conventional" computers).

You should rather use the optional types intptr_t and uintptr_t, from C99.

C11 (n1570), § 7.20.1.4

The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer: intptr_t.

The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer: uintptr_t.

Here is a small example:

#include <stdio.h>
#include <stdint.h>

int n = 42;
int *p = &n;
intptr_t i = (intptr_t)(void *)p;
int *q = (void *)i; 

printf("%d\n", *q);

Upvotes: 10

fuz
fuz

Reputation: 93172

If you want to have an integer type that is guaranteed to be big enough to hold a pointer, consider intptr_t (signed) or uintptr_t. The standard guarantees that these datatypes are big enough to hold a pointer. Nothing else might be assumed, especially not that long int is long enough.

Upvotes: 1

Related Questions