This question on SO deals with the char
<-> uint8_t
issue mainly from the perspective of the Strict Aliasing Rule. Roughly speaking, it clarifies that as long as uint8_t
is implemented as either char
or unsigned char
, we're fine.
I'm interested in understanding whether or not the possible incompatability of the signed/unsignedness of uint8_t
with char
matters when using reinterpret_cast
.
When I need to deal directly with bytes, I prefer using uint8_t
. However, the Winsock API deals with char*
s.
I would like to understand how to handle these conversions correctly, in order to not run into Undefined Behavior or other phenomenons that damage the portability of the app.
The following functions takes a std::array<uint8_t, 4>
and converts it to an uint32_t
- i.e., takes 4 bytes and converts them to an integer.
uint32_t bytes_to_u32(const std::array<uint8_t, 4>& bytes) {
return (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3];
}
However, the data incoming from the socket (using the recv
function) comes in char*
form.
One approach is the following:
std::array<uint8_t, 4> length_buffer;
int bytes_received = 0;
while (bytes_received < 4) {
bytes_received += recv(sock, reinterpret_cast<char*>(length_buffer.data()) + bytes_received, 4 - bytes_received, 0);
}
It seems to work on my machine. However - is this safe? If I'm not mistaken, on a different machine or compiler, a char
may be signed
, meaning the length_buffer
will hold wrong values after the conversion. Am I wrong?
I know that reinterpret_cast
does not change the bit pattern at all - it leaves the binary data the same. Knowing this, it still doesn't fully register in my brain whether or not this technique is the right way to go.
Please explain how to approach this problem.
EDIT: Also noting, after converting the char*
to uint8_t*
, I need to be able to convert the uint8_t*
to a valid numeric value, or sometimes test the numeric values of individual bytes in the buffer. In order to interpret the "commands" I was sent over the network, and send some back to the other side.