Search code examples
cpointerstype-conversiondoublevoid-pointers

In plain C, how to assign a void pointer value to a double


void foo(void* p) {
    double d = (double) p; // Doesn’t compile.
    printf(“%f\n”, d);
}

What I need is to be able to call

foo((void*) 13.0);

and have 13.0 printed.

Note

I need this in order to store distances (of type double) between source nodes and arbitrary nodes stored in a C hash map that is “void*” generic in graph search. See https://github.com/coderodde/BidirectionalDijkstra4Perl2


Solution

  • The standard way has been given by Eric's answer.

    But if the size of a void * is not smaller than the size of a double, you can store the representation of the double in a void *. From that point you cannot use the pointer for anything but extracting back the representation to a double object. Here is an example code demonstrating it:

    #include <stdio.h>    
    #include <assert.h>
    #include <memory.h>
    
    void foo(void* p) {
        double d;
        memcpy(&d, &p, sizeof(d));
        printf(" % f\n", d);
    }
    
    int main() {
        void* p;
        // ensure that the representation of a double can fit in a void *
        static_assert(sizeof(void*) >= sizeof(double), "sizeof(double) > sizeof(void *)");
        double d = 13.0;
        memcpy(&p, &d, sizeof(d));
        foo(p);
        return 0;
    }
    

    But beware: this should only be used as a workaround to cope with legacy code. The portability is limited to platforms where the size of a double is not greater than the size of a void * which is false on a 32 bits platform. Compiling above code in 32 bits mode raises a compilation error:

    error ...: sizeof(double) > sizeof(void *)