1

I have a std::string containing four bytes received from a serial port. These bytes represent two int16_t in little endian. Since the software is going to run on x86 only, there is no need to change the endianness.

My first approach to get the individual integer values was this:

std::string inData = ...; // inData.length() = 4
int16_t measurement[2];
measurement[0] = ( (int16_t)inData[0] << 8 ) | (int16_t)inData[1];
measurement[1] = ( (int16_t)inData[2] << 8 ) | (int16_t)inData[3];

Well, the result looked like undefined behaviour. I expected casting from inData[x] to int16_t would yield having the four MSB set to zero, but that seems not to be true. So I tried this:

const uint8_t *castedData = reinterpret_cast<const uint8_t*>(&inData[0]);
measurement[0] = ( (int16_t)castedData[0] << 8 ) | (int16_t)castedData[1];
measurement[1] = ( (int16_t)castedData[2] << 8 ) | (int16_t)castedData[3];

and it works as intended. However, is this the "correct" way? Or is there a way to achieve this without using reinterpret_cast?

I had a look at Converting unsigned chars to signed integer, but the accepted answer and the comments about aliasing confused me.

3
  • 1
    Both methods produces identical results for me. See ideone.com/bBKj6F Commented Feb 2, 2016 at 15:10
  • Use std::basic_string<unsigned char>. Commented Feb 2, 2016 at 15:32
  • (inData[0] << 8) | (inData[1] & 0x00FF)... no casts needed Commented Feb 2, 2016 at 15:49

1 Answer 1

1

Both are correct, the latter would be better with calling c_str() and casting the resulting pointer. The issue with former is that the std::string is most probably based on signed char. Therefore conversion to bigger int type will extend the sign bit and for example 0x80 will become 0xff80.

If you fix the original with:

( (uint8_t)inData[0] << 8 ) | (uint8_t)inData[1];

it will work too...

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.