0

I am quite new to C, and have been practicing with pointers. I understand that a void * pointer accepts a pointer of any kind, so this works fine:

void functionWithSingleVoidPointer(void *simplePointer)
{
    free(simplePointer);
}
int main()
{
    char *simplePointer = malloc(sizeof *simplePointer);
    functionWithSingleVoidPointer(simplePointer); //No warnings
    return 0;
}

However, I don't understand why this:

void functionWithDoubleVoidPointer(void **doublePointer)
{
    free(*doublePointer);
}
int main()
{
    char *simplePointer = malloc(sizeof *simplePointer);
    char **doublePointer = &simplePointer;
    functionWithDoubleVoidPointer(doublePointer);
}

gives me a warning:

warning: passing argument 1 of ‘functionWithDoubleVoidPointer’ from incompatible pointer type [-Wincompatible-pointer-types] ... note: expected ‘void **’ but argument is of type ‘char **’

Why doesn't the casting from char * to void * give any warning, but the casting from char ** to void ** does?

  • 1
    Not quite related to the question but a little advice: a `type**` is a **pointer to pointer**, not a **double pointer**. – Uduru Mar 24 '21 at 03:54
  • 1
    Does this answer your question? https://stackoverflow.com/questions/25427587/void-a-generic-pointer – aschepler Mar 24 '21 at 04:01
  • Does this answer your question? [Void \*\* a generic pointer?](https://stackoverflow.com/questions/25427587/void-a-generic-pointer) – mediocrevegetable1 Mar 24 '21 at 04:40

2 Answers2

5

A char* value points to a char object; a void* object can point to any kind of object. The conversion is safe (as long you don't do anything unsafe with the result).

A char** pointer value must point to a pointer object of type char* somewhere in memory. A void** pointer value must point to an object of type void*. Since char* and void* are different types, you can't just assume that you can safely treat an object of one type as if it were an object of the other type. (Most likely they have the same representation, but the language doesn't guarantee that.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

A void** is not a void pointer, that's it.
void** is a pointer to a void pointer, which only accept void pointers.

Uduru
  • 511
  • 2
  • 10