Well, both questions are concerned towards my compiling output, since I try to remove all warnings..
To the first question:
I'm xor'ing float values, 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 is a pointer to this class ClassXY *m_pParent;
m_Value is a var of a struct and m_fValue is defined as a float inside the struct.
Any idea how to get around the warning? (I know that I can disable the warning, but I have no idea to get a clean solution to it)
My second qustion would be:
The scenario is nearly the same though, only with int. Compiler is talking about information loss: warning: cast from ‘const ClassXY*’ to ‘uint32_t {aka unsigned int}’ loses precision [-fpermissive]
Without the -fpermissive compiler flag, I wouldn't be able to compile..
inline int ClassXY::GetInt(void) const
{
return (int)(m_pParent->m_Value.m_nValue ^ (int)this); // compiler warning for this line
}
And again, any idea on how to fix this?
Or is it inpossible without warnings, what I'm trying to accomplish?
To give you all an idea what it is about:
auto example = g_pClassXY->FindVar("example_var");
Then: float float_val = example->fValue; // direct access, value is wrong
To get the value right, the right approach would be: float float_val = example->GetFloat();
Thanks in advance!
To avoid a strict aliasing violation, the code could be:
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;
However there are still some issues:
this
is a 64-bit pointer.float
, causing undefined behaviour.If your intent is to "encrypt" a float, then the encrypted value should be stored as uint32_t
or a byte array, not as float
.
The first bullet point could be addressed by generating a random 32-bit mask for each instance, instead of using this
; or using uintptr_t
instead of uint32_t
.