Search code examples
cpointerscastingimplicit-conversionvoid-pointers

How can a void pointer hold data meant for non pointer variables?


I was practicing with void pointers when this code successfully compiled:

#include <stdio.h>


int main()
{
    void *x = (void*) 576;
    int *y = x;
    printf("%d\n", y);

    return 0;
}

I don't understand this. How can the literal 576 be type-casted to a void pointer? Additionally, notice how in the printf() function call, the dereference operator is missing from y. And yet it prints the value 576. And when I add the dereference operator to y, nothing prints to the terminal.

After a bit of research, I found out that NULL is just the literal 0 type-casted to a void pointer. Can anything be type-casted to a void pointer? Is the code I posted up dangerous?


Solution

  • A pointer of the type void * may be converted to a pointer of other object type.

    From 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.

    As for this call

    printf("%d\n", y);
    

    then you are trying to output a pointer using the conversion specifier %d that is designed to output integers. As a result such a call invokes undefined behavior.

    If you want to output a pointer you need to use conversion specifier %p as for example

    printf("%p\n", ( void * )y);
    

    If you want to output a pointer as an integer you need to include headers <stdint.h> and <inttypes.h> (the last header already contains the first header) and to write like

    #include <stdint.h>
    #include <inttypes.h>
    
    //...
    
    printf( "%" PRIuPTR "\n", ( uintptr_t )y );