xor'ing valor float & questão geral elenco sobre saída do compilador

votos
0

Bem, ambas as questões estão em causa para a minha saída de compilação, desde que eu tente remover todos os avisos ..

Para a primeira pergunta :
Estou xor'ing valores float, saída do compilador: 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 é um ponteiro para esta classe ClassXY *m_pParent;
m_Value é um var de uma estrutura e m_fValue é definida como uma bóia no interior da estrutura.

Alguma idéia de como contornar o aviso? (Eu sei que eu posso desativar o aviso, mas não tenho idéia para obter uma solução limpa para ele)

Minha segunda qustion seria:
O cenário é quase o mesmo, porém, apenas com int. Compiler está falando sobre a perda de informações: warning: cast from ‘const ClassXY*’ to ‘uint32_t {aka unsigned int}’ loses precision [-fpermissive]
Sem o sinalizador de compilador -fpermissive, eu não seria capaz de compilar ..

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

E, novamente, qualquer ideia sobre como consertar isso?
Ou é inpossible sem avisos, o que estou tentando realizar?

Para dar-lhe toda uma idéia do que se trata: auto example = g_pClassXY->FindVar(example_var);
Então: float float_val = example->fValue; // direct access, value is wrong
Para obter o valor correto, a abordagem correta seria:float float_val = example->GetFloat();

Desde já, obrigado!

Publicado 07/11/2018 em 23:52
fonte usuário
Em outras línguas...                            


1 respostas

votos
2

Para evitar uma estrita aliasing violação, o código poderia ser:

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;

No entanto, existem ainda algumas questões:

  • O código está mal formada sobre um sistema em que thisé um apontador de 64 bits.
  • Os valores float envolvidos pode ser um padrão de bits inválida para float, causando um comportamento indefinido.

Se sua intenção é "criptografar" float, então o valor criptografado devem ser armazenados como uint32_tou um array de bytes, não como float.

O primeiro ponto de bala pode ser endereçada através da geração de uma máscara de 32 bits aleatória para cada caso, em vez de usar this; ou utilizando uintptr_t, em vez de uint32_t.

Respondeu 08/11/2018 em 00:17
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more