Convert void* to const void**

Viewed 779

In CPP I use a C library, one of the method needs a const void ** as parameter.

In my class I have a property whose type is void *.

I tried to call the function by doing function(&my_property) but the compiler complained that it could not convert a void ** to a const void **.

To fix this issue I used a const cast and did function(const_cast<const void *>(&my_property)).

I try to avoid casting as much as possible and I would like to know if there is a "clean" way to do that without using a const cast.

3 Answers

Replicating your situation in a simple manner, let's say you have this code:

void function(const void **p)
{
    //...
}

int main()
{
    void *my_property;
    function(&my_property);
}

Using const_cast is safe, I don't think it's all that unclean, but you have alternatives, the best of wich would be to turn my_property into a const void*, suspecting that may not be an option, you may just use a const void* pointer to wich you would assign the original void*:

void *my_property;
const void *pp = my_property;
function(&pp);

The conversion is still there, but it's implicit.

As Quentin very accurately pointed out, this does not make a lot of sense, unless it's just to shut up the compiler.

Proper solution would be to turn my_property into const void*. Otherwise you might break a contract of function.

If the library is expecting an array of arrays using a cast probably wont fix it, if you can't check the library source you can guess. A manual conversion is a safe solution. Using new_cast_a_to_m() requires you to delete the array at some point but not the original array; struct X and the code aroud it is just for this example, new_cast_a_to_m() should work for you by itself.

#include <iostream>

struct X {
    int a = 0;
};

int c_foo (X ** x){
    return x[4][0].a;
}

template <typename V>
V ** new_cast_a_to_m(V * arr, size_t n){
    V ** nc = new V * [n];
    for(size_t i=0; i < n; i++){
        nc[i] = &arr[i];
    }
    return nc;
}

int main(void){

    X ** arr = new X * [5];
    arr[4] = new X;

    std::cout << "intended c_foo() -> " << c_foo(arr) << std::endl;

    X * brr = new X[5];
    X ** nrr = new_cast_a_to_m(brr, 5);
    std::cout << "casted c_foo() -> " << c_foo(nrr) << std::endl;

    delete [] nrr;
    delete arr[0];
    delete [] arr;

    return 0;
}
Related