Reputation: 49329
I am missing something obvious here but consider the following,
int k = 10;
int *p = &k;
int i = (int)p;
above produces,
warning: cast from pointer to integer of different size
and following,
int k = 10;
int *p = &k;
int i = p;
causes,
warning: initialization makes integer from pointer without a cast
a bit of googling lead me to,
Converting a pointer into an integer
which advices using uintptr_t,
int k = 10;
int *p = &k;
int i = (uintptr_t)p;
above works no errors no warnings. So my question is k is an int and p is an int pointer pointing to k why do i get an error dereference p?
Upvotes: 5
Views: 498
Reputation: 1022
int k = 10;
int *p = &k;
int i = *p;
Note the * before p on the last line. Dereference the pointer to get the int it points to.
EDIT: I'm not very familar with uintptr_t, but I ran the code int i = (uintptr_t)p; The result that is stored into i is the memory address of k, not 10. The cast tells the compiler that you really want to turn the address into an integer (so there's no warning; because you are insisting to the compiler that you know what you are doing) but does not dereference the pointer.
Upvotes: 9
Reputation: 78923
uintptr_t
is not meant as a type to do an intermediate cast to int
but used as such. If it is defined on a system (and yours seems to have it) it is the unsigned integer type where you don't loose information when you load it with a pointer value. So if you must, use uintprt_t
fully instead of int
. But this should be rare occasions, and in most cases I would bet, this is just a sign of bad design.
In any case int
is a bad idea from the start. If anything, a pointer value is just an position in a virtual memory space and seeing it as a signed value makes no sense to me at all.
Upvotes: 0
Reputation: 1688
You are setting i
equal to the address of k
(which is what p
holds). And the address value is an unsigned type. So when casting from the pointer, it complains because you are taking casting and unsigned value to signed.
Also pointers are different sized types based on the platform, so 32 bit pointers are smaller than 64. So if the pointer is a 8 byte unsigned, you are casting it down to a 4 byte signed.
Upvotes: 1
Reputation: 129
this is how it should look
int k = 10;
int *p = &k;
int i = *p;
here is how I think of it
k = 10
p = some address
&k = some address
*p = 10
Upvotes: 0
Reputation: 70909
You're playing with int to pointer casting, and that has no guarantee that the two even use the same amount of memory anymore. Actually it didn't have a guarantee of using the same size back when people did it, but for most platforms it just happened to work anyway.
Since you explicitly cast in the latter example, the compiler assumes it wasn't a mistake (or why would you have typed it out?). That's the reason for the difference in compiler output.
Note that if you didn't want to store the memory address of k into i, then the proper way to get K's value into i would be
int i = *p;
Upvotes: 1
Reputation: 18627
You aren't dereferencing the pointer, so you are assigning the address of the pointer to an int.
int i = *p;
Is what you most likely wanted.
Upvotes: 2
Reputation: 20609
You get an error because you didn't actually dereference p
, you just casted it (forcefully changed its type) from int*
. To dereference, you need to use the *
operator, like so:
int i = *p;
Upvotes: 3