Search code examples
cpointersdouble-pointer

Incompatible pointer types (double pointers)


In a function that asks a double pointer like this one:

#include <stdlib.h>

void    prueba(void **ap)
{
    *ap = NULL;
}

compiled with the following main:

#include <stdlib.h>
#include <stdio.h>

void    prueba(void **ap);

int        main(void)
{
    char *str;

    str = (char *)malloc(sizeof(char) * 5);
    prueba(&str);
    if (str == NULL)
        printf("NULL");
    return (0);
}

I get this warning with gcc:

main2.c:11:9: warning: incompatible pointer types passing 'char **' to parameter of type 'void **' [-Wincompatible-pointer-types]
        prueba(&str);
               ^~~~
main2.c:4:23: note: passing argument to parameter 'ap' here
void    prueba(void **ap);

But if i do the same but with simple pointers, that is give a pointer to char to a function who asks for a void pointer, gcc compiles without warnings, for example, the following compiles right: function:

#include <stdlib.h>

void    prueba(void *ap)
{
    ap = NULL;
}

main:

#include <stdlib.h>
#include <stdio.h>

void    prueba(void *ap);

int        main(void)
{
    char *str;

    str = (char *)malloc(sizeof(char) * 5);
    prueba(str);
    if (str == NULL)
        printf("NULL");
    return (0);
}

So my question is, why it works with simple pointers but it does not work with double pointers (or greater i guess)?


Solution

  • According to the C Standard (6.3.2.3 Pointers)

    1 A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

    So in the second code snippet a pointer of the type char * is implicitly converted to the type void * though the function does not make sense because it deals with a copy of its argument and therefore does not changes the original pointer.

    However the type void ** is not the same as the type void *. So the quote is not applicable for the type void ** and the compiler issues a diagnostic message because there is no implicit conversion from a pointer to any object type to a pointer of the type void **.