30

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?

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
Ann
  • 693
  • 3
  • 12
  • 17
  • 6
    Can you show an example? – Oliver Charlesworth Jun 07 '13 at 14:12
  • 6
    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). – Fred Foo Jun 07 '13 at 14:14
  • You have to cast a void pointer if you want to access its structure.(struct) –  Jun 07 '13 at 14:15
  • What exactly is your question? Why use `void` pointers or why to cast them? – alk Jun 07 '13 at 14:25
  • 1
    @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). –  Jun 07 '13 at 14:33
  • 1
    [This may be relevant here.](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – milleniumbug Jun 07 '13 at 14:41
  • 9
    [It is “code”, not “codes.”](http://english.stackexchange.com/questions/20455/is-it-wrong-to-use-the-word-codes-in-a-programming-context) –  Jun 07 '13 at 14:46

2 Answers2

22

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.

Community
  • 1
  • 1
wolfgang
  • 4,883
  • 22
  • 27
  • 2
    But argument 2 is invalid: one should not compile C code with a C++ compiler. –  Jun 07 '13 at 14:45
  • 6
    @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. – Adam Rosenfield Jun 07 '13 at 14:47
  • 2
    @H2CO3 Nevertheless, some people do it. I was trying to explain the phenomenon, not justify it. – wolfgang Jun 07 '13 at 14:49
  • 1
    3rd reason: You are forced by a brain-dead coding guideline. s/implicit cast/implicit conversion/ – undur_gongor Jun 07 '13 at 14:57
  • @undur: "I was just following orders" doesn't count. Good catch on the cast/conversion thing, though. – wolfgang Jun 07 '13 at 14:59
  • 1
    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. – xryl669 Jan 13 '22 at 11:34
  • @xryl669 Completely disagree! Record like **a->b = malloc(sizeof(*a->b))** tell you: allocating memory of size needed for **b** and assigning it to **b**. It is perfect and clear as for me. ;) – tvorez Jul 10 '23 at 20:50
16

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 */
}
Guillaume
  • 10,463
  • 1
  • 33
  • 47
  • 4
    You don't *need to;* a more readable (preferred by me) approach is `int *tmp = param; int val = *tmp;`. –  Jun 07 '13 at 14:38
  • @H2CO3 You have to if the pointer is a void type. As is in Guillaume's example. –  Jun 07 '13 at 14:42
  • 3
    @Armin You don't **have to,** I repeat - the cast can be avoided if you assign the pointer to a temporary. –  Jun 07 '13 at 14:43
  • @H2CO3 But you **have to** if you don't use a temp , as is shown in his example. –  Jun 07 '13 at 14:44
  • 1
    @Armin That's right, but that's not what I'm saying - I rather suggest that it's not globally inevitable. –  Jun 07 '13 at 14:45