Search code examples
cpointersvoid-pointersgeneric-programming

Confused about the pointers and generic(void) pointers in C


I missed a couple classes, and don't really understand the flowing lecture slide's examples about the void pointer.

  1. In the line "no,no,no", why we cannot deference P since P has been assigned a real pointer type q?

  2. In the line " ?? ", is it legal to cast a pointer to a integer? ( I think it can compile because C doesn't check cast, but don't know what kind of result it is going to get

in this example Conversion of integer pointer to integer
he casted *p = 10; a = (int)p; and someone answered that a is going to be a very large value. but in my case,is (int) *p... Is it the same case as the example that I gave above?

  1. In the last line, I am confused about the expression. Is * ((int *)p) actually = p? Thanks!

enter image description here

enter image description here


Solution

  • "void*" means "this value is a pointer to something, but I'm not telling you what it points to". Start with this statement, and everything makes sense.

    So it should be clear that you can't dereference a void*, because nobody told you what it points to! If you don't know whether it points to an int, a char, or some struct, what do you think should happen if you dereference it?

    In C, you can assign a void* to any pointer, for example to an int*. The compiler doesn't know what the void* points to, but when you write r = p; the compiler says "I hope you know what you are doing, I trust you. " (A C++ compiler in the same situation doesn't trust you). If the void* p did indeed point to an int, everything is fine. Otherwise, things are more or less bad.

    The ?? one is wrong. You can't dereference *p. Doesn't matter what you do afterwards, *p isn't allowed. And no pointer is cast to an integer. There is an attempt to dereference a pointer, which isn't allowed. The result of the dereference couldn't be anything useful since you don't know what p points to, so you have nothing useful to cast to an int.

    Now what happens in * (int *) p: p is a void * - a pointer to something, but you don't know what it points to. (int * )p is a cast: p is converted to an int*. That means the compiler will believe that (int*)p points to an int - that may or may not be true. * (int * ) p dereferences the int*: So in total, you convinced the compiler that p points to an int, and to read the int that p hopefully points to. If p did actually point to an int, it's fine. If p didn't point to an int, you're in trouble.