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 and float32 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 a float32 *.
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.