Search code examples
c++cvoid-pointers

C vs. C++, handling of void** pointers


I found out that using a C compiler the code below works but not with a C++ compiler. I understand that casting to void** is the correct usage but I can't understand why it compiles with the C compiler even if I use the void* (commented out).

#include <stdio.h>

int fn(void **arg)
{
    int *pvalue = *(int**)arg;
    *pvalue = 200;
    return 0;
}

int main()
{
    int value = 99;
    int *pvalue = &value;

    // fn((void *)&pvalue);  // works only in C
    // error C2664: 'int fn(void **)': cannot convert argument 1 from 'void *' to 'void **'

    fn((void **)&pvalue);    // correct, works for both C/C++

    printf("%d", value);
    return 0;
}

Can someone explain why this is the case?


Solution

  • In C there is allowed to assign a pointer of the type void * to a pointer of other type. This takes place in this call

    fn((void *)&pvalue)
    

    where the argument has the type void * that is assigned to the function parameter that has the type void **.

    int fn(void **arg)
    {
        int *pvalue = *(int**)arg;
        *pvalue = 200;
        return 0;
    }
    

    However such an assignment in general is unsafe. For example the value of a pointer of the type void * can not be properly aligned to be assigned to a pointer of other type.

    So it was decided to not allow such an assignment in C++ to make programs more safer.