关于编译器输出的异或浮点值和一般转换问题

xor'ing float value & general cast question concerning compiler output

好吧,这两个问题都与我的编译输出有关,因为我试图删除所有警告..

对于第一个问题
我正在异或浮点值,编译器输出: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

inline float ClassXY::GetFloat(void) const
{
    uint32_t xored = *(uint32_t*)&m_pParent->m_Value.m_fValue ^ (uint32_t)this; // compiler warning for this line
    return *(float*)&xored;
}

m_pParent 是指向此 class ClassXY *m_pParent;
的指针 m_Value 是结构的 var,m_fValue 被定义为结构内的浮点数。

知道如何绕过警告吗? (我知道我可以禁用警告,但我不知道如何得到一个干净的解决方案)

我的第二个问题是:
场景几乎相同,只是使用了 int。编译器正在谈论信息丢失:warning: cast from ‘const ClassXY*’ to ‘uint32_t {aka unsigned int}’ loses precision [-fpermissive]
没有 -fpermissive 编译器标志,我将无法编译..

inline int ClassXY::GetInt(void) const
{
    return (int)(m_pParent->m_Value.m_nValue ^ (int)this); // compiler warning for this line
}

再说一遍,有什么办法解决这个问题吗?
还是在没有警告的情况下不可能实现我想要完成的目标?

为了让大家了解它是关于什么的: auto example = g_pClassXY->FindVar("example_var");
然后:float float_val = example->fValue; // direct access, value is wrong
要获得正确的值,正确的方法是:float float_val = example->GetFloat();

提前致谢!

为避免严格的别名冲突,代码可以是:

static_assert( sizeof(float) <= sizeof(uint32_t), "size problem" );
uint32_t xored{};
memcpy(&xored, &m_pParent->m_Value.m_fValue, sizeof xored);
xored ^= reinterpret_cast<uint32_t>(this);

float ret;
memcpy(&ret, &xored, sizeof ret);
return ret;

但是还有一些问题:

  • 代码在 this 是 64 位指针的系统上格式错误。
  • 涉及的浮点值可能是 float 的无效位模式,导致未定义的行为。

如果您的目的是 "encrypt" 浮点数,则加密值应存储为 uint32_t 或字节数组,而不是 float

第一个要点可以通过为每个实例生成一个随机的 32 位掩码来解决,而不是使用 this;或使用 uintptr_t 而不是 uint32_t.