Ahh, nothing like the pre-C99 C standard... Where the following code just worked on little-endian machines:
union UNION_WORD {
WORD word;
BYTE bytes[2];
};
union UNION_WORD test;
test.word = 24576;
test.bytes[0] = 8;
And the data stored in test would be equivalent to 24584
when reading test.word
. Sadly this behavior is undefined today in C and has always been undefined in C++.
As a preface, I'm an assembly kinda guy, but I want to give C++ another chance to redeem itself. I want to create a class like UNION_WORD that can be manipulated by individual bytes or the whole word, which is valid C++ and well-defined. The key here is that the C++ code:
WORD word = 24576;
BYTE byte = 8;
UNION_WORD test = 0;
test.word = word;
test.bytes[0] = byte;
compiles into something extremely simple like the following assembly (8-bit architecture):
ldi r1, 0x00
ldi r2, 0x60
ldi r3, 0x08
mov r4, r1
mov r5, r1
mov r4, r1
mov r5, r2
mov r4, r3
This code assumes everything can be done in registers without using ram. When finished, 0x6008
(24584) will be in [r4:r5]
. My biggest concern is making sure the compiler doesn't cache bytes[]
or word
in the registers, assuming it hasn't been updated, because of a reinterpret_cast
or the like. I custom operators may need to be defined. Most important thing is optimization for speed. How can this type of punning be achieved in c++?