Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast pointer to larger int

Tags:

c

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]

like image 220
Ben Clifford Avatar asked Nov 08 '12 11:11

Ben Clifford


1 Answers

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);
like image 140
md5 Avatar answered Oct 12 '22 01:10

md5