I'm currently writing a runtime for my compiler project and I want general and easy to use struct for encoding different types (the source language is scheme).
My current approach is:
struct SObj {
SType type;
uint64_t *value;
};
Pointer are always 64 or 32 bit wide, so shouldn't it be possible to literally put a float into my value? Then, if I want the actual value of the float, I just take the raw bytes and interprete them as a float.
Thanks in advance.
Not really.
When you write C++ you're programming an abstraction. You're describing a program. Contrary to popular belief, it's not "all just bytes".
Compilers are complex. They can, and will, assume that you follow the rules, and use that assumption to produce the most efficient "actual" code (read: machine code) possible.
One of those rules is that a uint64_t*
is a pointer that points to a uint64_t
. When you chuck arbitrary bits into there — whether they are identical to the bits that form a valid float
, or something else — it is no longer a valid pointer, and simply evaluating it has undefined behaviour.
There are language facilities that can do what you want, like union
. But you have to be careful not to violate aliasing rules. You'd store a flag (presumably, that's what your type
is) that tells you which union
member you're using. Make life easier and have a std::variant
instead, which does all this for you.
That being said, you can std::memcpy
/std::copy
bits in and copy bits out, in say a uint64_t
as long as they are a valid representation of the type you've chosen on your system. Just don't expect reinterpret_cast
to be valid: it won't be.