I'm trying to work with low level types like floats and doubles, in a program where they are 'encrypted' however, when I tried to create a structure that looked like this:
struct rgba
{
float r, g, b, a;
};
//and reference it like this:
rgba color;
reinterpret_cast<uint64_t>(color.a) ^= 0xDEADBEEF;
this would not work as the cast was an invalid type conversion. this led me down a rabbit trail to find a method to cast this without pointers or syntax sugar.
//I wanted to avoid this:
*retinterpret_cast<uint64_t*>(&color.r);
and this leads to the code I have now.
#include <iostream>
union test
{
struct
{
uint64_t a;
uint64_t b;
char end[1];
};
uint8_t pad[];
test(uint64_t a1, uint64_t a2)
{
a = a1;
b = a2;
end[0] = *const_cast<char*>("\0");
}
};
struct internal
{
float r, g, b, a;
};
union rgba
{
struct
{
float r, g, b, a;
};
struct
{
uint8_t fhalf[sizeof(internal) / 2];
uint8_t lhalf[sizeof(internal) / 2];
};
};
int main()
{
rgba color = rgba{ { 0.127f, 0.127f, 0.127f, 1.f } };
test structure_ = test{reinterpret_cast<uint64_t>(color.fhalf), reinterpret_cast<uint64_t>(color.lhalf)};
std::cout << "Result 0x" << std::hex << structure_.a << structure_.b << std::endl;
}
I have two problems and two questions, firstly this is currently outputting a seemingly random value as if I'm getting some data off the stack somewhere or garbage from memory.
and second I would rather not have to define the struct 'internal' outside of the union but I can't reference its members if I name it inside the union e.g.
union rgba
{
struct internal
{
float r, g, b, a;
};
struct
{
uint8_t fhalf[sizeof(internal) / 2];
uint8_t lhalf[sizeof(internal) / 2];
};
};
//
rgba color = rgba{ { 0.127f, 0.127f, 0.127f, 1.f } };
//this fails:
test structure_ = test{reinterpret_cast<uint64_t>(color.r), reinterpret_cast<uint64_t>(color.b)};
so with that failing that leads me to my questions
TLDR;
how do you reference named member structures of a union and; where am I getting the random garbage from and is there a better way to cast structs without unions?
User contributions licensed under CC BY-SA 3.0