In the following example, the representation value is uint32_t
copied to an array uint8_t
. This is done using std::memcpy
. Since I understand the C ++ standard, this is completely legal: we access an object of type T
through T*
cast to unsigned char*
. There is no problem with an alias, there is no problem with alignment.
The other way is less obvious. We get an object representation T
through unsigned char*
what is legal. But does access to terms include change?
Of course, there are no aliases and problems with the alias. However, there are problems if the values in the buffer s
come from a foreign source: we must ensure the correct orientation and skip the view of the trap. You can check the correct orientation so that it can be solved. But what about traps? How can we avoid this? Or do uint
-types have no trap representations, and do not speak double
?
I know that another (more compatible?) Way will shift the values uint8_t
to the object uint_t
. We must still submit to the content, but it should safely drop traps.
But shifts of large types at small μC (8-bit) can be quite expensive!
The next question is: if the second attempt (see below in the code) is equivalent to the approach memcpy
regarding legality and functionality? Well, it looks like the version is memcpy
more optimized.
#include <cstdint>
#include <cstring>
#include <cassert>
typedef uint32_t utype;
constexpr utype value = 0x01020304;
int main() {
utype a{value};
utype b{0};
uint8_t s[sizeof(utype)]{};
std::memcpy(s, &a, sizeof(utype));
assert(s[0] == (value & 0xff));
std::memcpy(&b, s, sizeof(utype));
assert(b == value);
const uint8_t* ap = reinterpret_cast<const uint8_t*>(&a);
s[0] = ap[0];
s[1] = ap[1];
s[2] = ap[2];
s[3] = ap[3];
assert(s[0] == (value & 0xff));
uint8_t* bp = reinterpret_cast<uint8_t*>(&b);
bp[0] = s[0];
bp[1] = s[1];
bp[2] = s[2];
bp[3] = s[3];
assert(b == value);
}
source
share