代码之家  ›  专栏  ›  技术社区  ›  Stefan

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

  •  0
  • Stefan  · 技术社区  · 6 年前

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

    第一个问题 :
    我在异或浮点值,编译器输出: 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;
    }
    

    mu pParent是指向此类的指针 ClassXY *m_pParent;
    m\u Value是结构的一个var,m\u fValue被定义为结构内部的一个float。

    你知道怎么避开警告吗(我知道我可以禁用警告,但我不知道如何获得一个干净的解决方案)

    我的 可能是:
    不过,情况几乎相同,只有int.Compiler谈到了信息丢失: warning: cast from ‘const ClassXY*’ to ‘uint32_t {aka unsigned int}’ loses precision [-fpermissive]
    如果没有-fppermission编译器标志,我将无法编译。。

    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();

    1 回复  |  直到 6 年前
        1
  •  2
  •   M.M    6 年前

    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

    uint32_t 或字节数组,而不是 浮动

    ; 或使用 uintptr_t 而不是 第32页