A standard C way to reinterpret the bytes of an unsigned long
as a float
is:
y = (union { unsigned long u; float f; }) { x } .f;
This code defines a compound literal that is a union, and it initializes the union with the value of x
, which should be an unsigned long
. Then it accesses the f
member of the union, which is a float
. This float
value is assigned to y
, which should be a float
.
Thus, assuming the declaration of ApplicationApi
must remain the same and that the void *DataPtr
it is passed is the result of converting a pointer to a float
to a pointer to void
, its definition could be:
void ApplicationApi(void *DataPtr)
{
* (float32 *) DataPtr =(union { unsigned long u; float32 f; }) { unsignedLong_val } .f;
}
Notes about this code:
- This requires that
unsigned long
andfloat32
have the same size. - It is undesirable for
unsignedLong_val
to have file scope. It would be preferable to pass it as a parameter. - There is no reason inherent in this code that DataPtr should be passed as a
void *
. It could be passed as afloat32 *
.
Notes about code leading up to this code:
- The way that the bytes have been assembled in the
unsigned long
may have endian issues. - In C implementations that are currently rare, an
unsigned long
could have trap values that prevent it from being used to hold arbitrary bytes.
About the C standard and reinterpreting bytes:
- Reinterpreting bytes through a union is the result of C 2011 (N1570) 6.5.2.3 3, which says that an expression using the
.
operator and a member name has the value of the named member. Note 95 of the standard indicates that this may be used to reinterpret bytes. - Another supported way to reinterpret bytes is by converting a pointer to a pointer to a character type and using the new pointer to copy bytes, per 6.3.2.3 7. (
memcpy
is sometimes used for this.) - 6.3.2.3 7 defines this behavior only for pointers to character types. For other types, the C standard generally does not define the behavior of converting a pointer to a pointer of another type and dereferencing the result. Therefore, the behavior of code that does this is undefined. Even if it appears to work in a test, it may later fail due to compiler optimizations or other effects.