void* is literally float, how to cast?
If I understand correctly, your library is returning a float value in a variable whose declared type is void *
. The safest way to get it back out again is with a union
:
#include <assert.h>
static_assert(sizeof(float) == sizeof(void *));
union extract_float {
float vf;
void * vp;
};
float foo(...)
{
union extract_float ef;
ef.vp = problematic_library_call(...);
return ef.vf;
}
Unlike the approach in the accepted answer, this does not trigger undefined behavior.
xNidhogg
Updated on July 22, 2022Comments
-
xNidhogg almost 2 years
So I'm using this C library in my C++ app, and one of the functions returns a void*. Now I'm not the sharpest with pure C, but have heard that a void* can be cast to pretty much any other *-type. I also know that I expect a float at the end somewhere from this function.
So I cast the void* to a float* and dereference the float*, crash. darn!. I debug the code and in gdb let it evaluate
(float)voidPtr
and low and behold the value is what I expect and need!But wait, it's impossible to the same during compile time. If I write
float number = (float)voidPtr;
it doesn't compile, which is understandable.So now the question, how do I get my float out of this fricking void*?
EDIT: Thanks to H2CO3 this was solved, but I see lots of answers and comments appearing and dissappering not believing that I could do (float)voidPtr in gdb. here is the screenshot.
-
jww about 6 years"The safest way to get it back out again is with a union..." - Not in C++. Accessing an inactive union member is undefined behavior. I believe the safest way is a
memcpy
. -
zwol about 6 years@jww That is a bug in the C++ standard that should have been fixed over a decade ago. Any C++ compiler that doesn't implement the C99+errata semantics for unions is also buggy.