Search code examples
clanguage-lawyerplatform-agnostic

Is storing a byte in a void pointer cross-platform safe?


void *vp = (void *)5;
uint8_t i = (uint8_t)vp;

Will i == 5 on all 8-bit and higher cpus? What are the risks doing this? Is there a better way to have a variable store either an 8-bit integer literal or a pointer in C99?

I have an array of function pointers to functions that take a void *. Some functions need to interpret the void * as a uint8_t.


Solution

  • void *vp = 5; should not compile; the C standard at least requires the compiler to issue a diagnostic message. You can request the conversion with void *vp = (void *) 5;, and you can request the reverse conversion with (uint8_t) vp. The C standard does not guarantee this will reproduce the original value. (Conversions involving pointers are specified in C 2018 6.3.2.3.) It is likely to work in most C implementations.

    An alternative that would be defined by the C standard would be to use offsets into some sufficiently large object you already have. For example, if you have some array A, and you want to store some small number n in a void *, then you can do:

    void *vp = (char *) A + n; // Point n bytes into the object A.
    

    and you can recover the number with:

    (char *) vp - (char *) A // Subtract base address to recover offset.