In the line "no,no,no", why we cannot deference P since P has been
assigned a real pointer type q?
int a =2, *q = a, *r; //line 1
void *p; //line 2
p = q; // line 3
r = p; // line 4
With line 3 above, you are assigning the pointer q
to p
. But it doesn't change the type of p
- it's still a void pointer. So you can't dereference it. So the following is invalid:
printf("%d\n", *p); // p is a void pointer - dereferencing here is illegal
Alternatively, you can do:
printf("%d\n", *((int*) p)); // p is a void pointer
The above is valid. Because, we convert p
to int *
before dereferencing it. Consider an example,
void func(void *p)
{
// what's `p` point to here?
}
int main(void)
{
int i = 5;
long x = 10;
void *p;
p = &i; // line 1
p = &x; //line 2
func(p);
}
You can comment out either line1 or line2 but is there anyway in func()
to know whether p
is pointing to a long
data or int
data? This is no different to your case.
But the conversion from void *
to type *
(data pointer) is always necessary before accessing the data its pointing to. Note that it can't be any data pointer though. For example,
int i = 42;
float f = 4.0;
void *p = &f;
printf("%d\n", *((int*))p); // wrong!
This is illegal. p
points to a float *
. Dereferencing as if it's pointing to a int
data is wrong.
In the line " ?? ", is it legal to cast a pointer to a integer?
printf("%d\n", (int) *p);
Since p
being a void*
, you are not allowed dereference in the first place. The cast after dereferencing doesn't change anything and the dereferencing is illegal.
If you were to cast the pointer itself like:
printf("%d\n", (int)p);
This has implementation-defined behaviour in C. C also provides intptr_t
/uintptr_t
types for the integer to pointer conversions.