XOR-значение с плавающей точкой и общий вопрос литого относительно вывода компилятора

голоса
0

Ну, оба вопроса касается к моей компиляции продукции, так как я стараюсь, чтобы удалить все предупреждения ..

К первому вопросу :
Я XOR - значения с плавающей запятой, вывод компилятора: 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 определяется как поплавок внутри структуры.

Любая идея, как обойти предупреждение? (Я знаю, что я могу отключить предупреждение, но я понятия не имею, чтобы получить чистый раствор к нему)

Мой второй qustion будет:
сценарий почти такой же , хотя, только с междунар. Компилятор говорит о потере информации: 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
}

И снова, любая идея о том , как это исправить?
Или это inpossible без предупреждений, что я пытаюсь достичь?

Чтобы дать вам всю идею , что это такое: auto example = g_pClassXY->FindVar(example_var);
Тогда: Для того, float float_val = example->fValue; // direct access, value is wrong
чтобы получить правильное значение, правильный подход будет:float float_val = example->GetFloat();

Заранее спасибо!

Задан 07/11/2018 в 23:52
источник пользователем
На других языках...                            


1 ответов

голоса
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;

Однако есть еще некоторые вопросы:

  • Код плохо формируется в системе , где this64-битный указатель.
  • Значения с плавающей точкой , связанные может быть недействительна битовый шаблон для float, вызывая неопределенное поведение.

Если ваша цель состоит в «шифровать» поплавок, то зашифрованное значение должно быть сохранено в качестве uint32_tили массива байт, а не как float.

Первая пуля может быть решено путем генерации случайной 32-битовой маски для каждого экземпляра, вместо того чтобы использовать this; или использовать uintptr_tвместо uint32_t.

Ответил 08/11/2018 в 00:17
источник пользователем

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