void*是字面上的浮点数,如何投射?

xNi*_*ogg 7 c c++ casting void void-pointers

所以我在我的C++应用程序中使用这个C库,其中一个函数返回一个void*.现在我对纯C来说并不是最敏锐的,但是听说过一个void*可以被投射到几乎任何其他的*类型.我也知道我希望在这个函数的某个地方有一个浮点数.

所以我将void*转换为float*并取消引用float*,崩溃.该死的!我调试代码并在gdb中让它评估(float)voidPtr和低,并看到值是我期望和需要的!

但是等等,在编译期间不可能一样.如果我写float number = (float)voidPtr;它不编译,这是可以理解的.

所以现在的问题是,如何让我的浮动脱离这个虚弱的空虚*?

编辑:感谢H2CO3,这已经解决了,但我看到很多答案和评论出现并且不再相信我可以在gdb中做(浮动)voidPtr.这是截图.

在此输入图像描述

小智 12

尝试使用指针:

void *theValueAsVoidPtr = // whatever

float flt = *(float *)&theValueAsVoidPtr;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这假设`sizeof(float)== sizeof(void*)`可能不是真的,在这种情况下,这会调用未定义的行为. (8认同)
  • 这有效,我错过了额外的 &。不确定现在发生了什么或为什么会发生这种情况,但它有效。谢谢。 (2认同)
  • @xNidhogg 说明:指针的类型安全性比非指针弱。你不能将 `void *` 转换为 `float`,但你可以将 `void **` 转换为 `float *`。现在,当您这样做并取消引用 `theValueAsVoidPtr` 变量的地址时,您将获得该变量的 *contents*,只是另一种类型 - 这称为类型双关语。请参阅[标有“邪恶浮点位级黑客”的行](http://en.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code)。 (2认同)

zwo*_*wol 8

如果我理解正确,你的库在声明类型为的变量中返回一个浮点void *.将它重新取回的最安全方法是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;
}
Run Code Online (Sandbox Code Playgroud)

与接受的答案中的方法不同,这不会触发未定义的行为.