Is this a safe way to load objects from vector of uint8_t by pointer?

Viewed 418

I have a std::vector<uint8_t> buffer; I want to load a datatype which is larger than uint8_t (in this example uint16_t target, but could be anything). I know that the content of this object has been copied into position size_t ID in buffer.

As far as I can tell, it is possible to copy the target with:

uint16_t target = *((uint16_t*) &buffer[ID]);

It works with gcc version 9.3.0 on Ubuntu using C++17.

But it certainly looks unintended. So is this safe to use? That is, as long as I know for certain that ID+sizeof(target) is within the buffer, can I be sure that this will compile and run without crashing on all OS?

1 Answers

No, it isn't. You cannot "pretend" a uint16_t exists where it does not.

There are some circumstances where such type punning is safe. For example, you can reinterpret an existing object of your desired type as a sequence of bytes (through a char*, unsigned char* or std::byte*), but the opposite is not true. (ref)

C++ is quite picky about what objects "exist", and you have to follow the rules of the language to make objects exist properly before you use them. It's not all just bytes. The compiler's "optimisations" can break your program's intended behaviour even before we get to the lower-level issues of alignment etc on actual computers.

To make this safe, you will need to copy the bytes into a fresh uint16_t:

uint16_t target = 0;
std::copy(
   reinterpret_cast<const char*>(&buffer[ID]),
   reinterpret_cast<const char*>(&buffer[ID]) + sizeof(uint16_t),
   reinterpret_cast<char*>(&target)
);

… or the shorter:

uint16_t target = 0;
std::memcpy(&target, &buffer[ID], sizeof(uint16_t));

Notice that here we are making use of the aliasing exemption I described above, to reinterpret a uint16_t as a sequence of bytes, writing into that sequence.

So, these versions are safe, as long as the bytes you are copying indeed form a valid representation of a uint16_t on your system (which is quite easy to guarantee for mainstream platforms).

Related