Search code examples
c++pointerscastingtype-conversionpointer-to-pointer

Casting object pointer to double void pointer (pointer to pointer to void)


I have a class method in a library (can't change it) which takes a double void pointer as one of its arguments. The declaration is as follows:

bool Queue::pop(void **packet, int &size, unsigned short &sn)

In my application code, I want to pass this function a pointer to another kind of object, in this case a GstBuffer pointer type. It seems like I can do this without any compiler errors if I cast the pointer to (void**) as in the following snippet but I have doubts if that will lead to correct behaviour. Is it valid to convert the pointer like this?

guint16 sn;
int size;
GstBuffer *buf; 
Queue *Q = ... // create a Queue instance
Q->pop((void **)&buf, size, sn);  // is this conversion valid?
size = gst_buffer_get_size(buf);

Solution

  • For all intents and purposes a void pointer can hold addresses of any object (data type), i.e. it can point to any object, and can be typecasted to any object, your code is valid, I would just use a more idiomatic cast:

    Q->pop(reinterpret_cast<void**>(&buf), size, sn);
    

    §7.3.12 Pointer conversions [conv.ptr]

    1. A prvalue of type “pointer to cv T”, where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The pointer value (6.8.3) is unchanged by this conversion.

    Example:

    void example(void **packet){
        std::cout << *packet << "\n";                   // pointer value
        std::cout << packet << "\n";                    // pointer address
        std::cout << **reinterpret_cast<int**>(packet); // value
    }
    
    int main() 
    {
        int* x = new int(20);
        std::cout << x << "\n";                         // pointer value
        std::cout << &x << "\n";                        // pointer address
        example(reinterpret_cast<void**>(&x));       
        delete x;
    }
    

    Output:

    0xb83eb0
    0x7ffc181ab2c8
    0xb83eb0
    0x7ffc181ab2c8
    20
    

    The explicit cast is even only needed because it's a pointer to pointer otherwise the conversion would be implicit, no cast would be needed.