Union casting initialization and referencing internal structures

0

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?

c++
unions
c++20
asked on Stack Overflow Dec 16, 2020 by Exceptis

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0