Why type cast a void pointer?

70,222

Solution 1

There are two reasons for casting a void pointer to another type in C.

  1. If you want to access something being pointed to by the pointer ( *(int*)p = 42 )
  2. If you are actually writing code in the common subset of C and C++, rather than "real" C. See also Do I cast the result of malloc?

The reason for 1 should be obvious. Number two is because C++ disallows the implicit conversion from void* to other types, while C allows it.

Solution 2

You need to cast void pointers to something else if you want to dereference them, for instance you get a void pointer as a function parameter and you know for sure this is an integer:

void some_function(void * some_param) {
    int some_value = *some_param; /* won't work, you can't dereference a void pointer */
}

void some_function(void * some_param) {
    int some_value = *((int *) some_param); /* ok */
}
Share:
70,222

Related videos on Youtube

Ann
Author by

Ann

Updated on July 09, 2022

Comments

  • Ann
    Ann almost 2 years

    Being new to C, the only practical usage I have gotten out of void pointers is for versatile functions that may store different data types in a given pointer. Therefore I did not type-cast my pointer when doing memory allocation.

    I have seen some code examples that sometimes use void pointers, but they get type-cast. Why is this useful? Why not directly create desired type of pointer instead of a void?

    • Oliver Charlesworth
      Oliver Charlesworth almost 11 years
      Can you show an example?
    • Fred Foo
      Fred Foo almost 11 years
      You don't need to cast from void* because the language defines an automatic conversion from void* to any other type of pointer, but not all programmers are aware of this (not even all C book authors, unfortunately).
    • Admin
      Admin almost 11 years
      You have to cast a void pointer if you want to access its structure.(struct)
    • alk
      alk almost 11 years
      What exactly is your question? Why use void pointers or why to cast them?
    • Admin
      Admin almost 11 years
      @larsmans More precisely, the C standard defines implicit compatibility between void * all data pointer types. Function pointers are out of the game (if, however, your system is POSIX, and why would any sane programmer use anything non-POSIX, then function pointers are compatible with void * too).
    • milleniumbug
      milleniumbug almost 11 years
    • Admin
      Admin almost 11 years
  • Admin
    Admin almost 11 years
    You don't need to; a more readable (preferred by me) approach is int *tmp = param; int val = *tmp;.
  • Admin
    Admin almost 11 years
    @H2CO3 You have to if the pointer is a void type. As is in Guillaume's example.
  • Admin
    Admin almost 11 years
    @Armin You don't have to, I repeat - the cast can be avoided if you assign the pointer to a temporary.
  • Admin
    Admin almost 11 years
    @H2CO3 But you have to if you don't use a temp , as is shown in his example.
  • Admin
    Admin almost 11 years
    But argument 2 is invalid: one should not compile C code with a C++ compiler.
  • Admin
    Admin almost 11 years
    @Armin That's right, but that's not what I'm saying - I rather suggest that it's not globally inevitable.
  • Adam Rosenfield
    Adam Rosenfield almost 11 years
    @H2Co3: True, but sometimes you have code defined in header files in macros or inline functions which is meant to be usable in both C and C++ code which includes those headers.
  • wolfgang
    wolfgang almost 11 years
    @H2CO3 Nevertheless, some people do it. I was trying to explain the phenomenon, not justify it.
  • undur_gongor
    undur_gongor almost 11 years
    3rd reason: You are forced by a brain-dead coding guideline. s/implicit cast/implicit conversion/
  • wolfgang
    wolfgang almost 11 years
    @undur: "I was just following orders" doesn't count. Good catch on the cast/conversion thing, though.
  • xryl669
    xryl669 over 2 years
    Reason 3: To tell people looking at your code that this area of memory is of that type, since a->b = malloc(sizeof(*a->b)) doesn't tell anything while a->b = (struct Monster*)malloc(sizeof(*a->b)) does.