好吧,这两个问题都与我的编译输出有关,因为我试图删除所有警告。
回答第一个问题:
我将浮点值异或,编译器输出:
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是指向此类ClassXY *m_pParent;
的指针
m_Value是一个结构变量,而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();
谢谢!
答案 0 :(得分:2)
为避免严格的别名冲突,代码可以是:
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
或字节数组,而不是float
。
可以通过为每个实例生成一个随机的32位掩码来解决第一个要点,而不是使用this
;或使用uintptr_t
代替uint32_t
。