-1

I use Qt serial to send a command through a serial port. The command contains a a signed 16 bit integer (xx) that can range from -4096 to 4096 with the high byte send first. The command is created as follows:

int16_t xi = 0;

for (int i=0; i<280; i++){
    xi = i;

    // index =     0   1   2  3   4   5
    // command = {'A','w','x','x','L','H'}
    unsigned char command[6] = {'A','w','x','x','L','H'};

    command[2] = xi >> 8;
    command[3] = xi & 0xFF;

    int len = strlen((char*)command);
    qDebug()<<"strlen: "<<len;
}

The command works fine for all values except between 0 and 256. I don't understand why I get a string with a length of 2 for values between 0 and 256? What I'm doing wrong? Any help is appreciated.

Edit: How could I change command[2] = xi >> 8; (or some other part) to avoid truncation and to get the full command for all integers between -4096 and 4096?

devHolz
  • 1
  • 1
  • 1
    `strlen` from https://en.cppreference.com/w/cpp/string/byte/strlen : _Returns the length of the given byte string, that is, the number of characters in a character array whose first element is pointed to by str up to and **not including the first null character. The behavior is undefined if there is no null character in the character array pointed to by str.**_ – Amadeus Jun 26 '19 at 14:15
  • [Why does strlen() return strange result when array doesn't contain null terminator?](https://stackoverflow.com/q/33938611/995714) – phuclv Jun 27 '19 at 00:08

1 Answers1

1

The underlying issue is in the command[2] = xi >> 8; section.

When you shift 8-bit right the 3rd element of the array, it becomes 0 as an int(null terminator). After that operation, strlen returns 2 because the 3rd element is a null terminator. Since after 256, shifting 8-bit right doesn't make the value 0, strlen works as expected. However, the behaviour is undefined, because strlen expects your string to be null terminated.

xeco
  • 184
  • 14
  • Except when there are no null values in the array, the behaviour is undefined, because `strlen` requires the input to be a null terminated array. – eerorika Jun 26 '19 at 15:28
  • wrong. `char` is often a signed type and right shift on a signed type is often arithmetic shift, so shifting values between 128 and 255 will not produce 0 in that case – phuclv Jun 27 '19 at 00:07
  • @phuclv I came to this conclusion after testing and debugging the code. So, it is not wrong. – xeco Jun 27 '19 at 06:18
  • debugging helps you know what happens in that specific case, not everything the standard allows. In this case you're lucky because xi < 32768 so the result isn't negative – phuclv Jun 27 '19 at 06:23
  • @eeroika Yes, exactly. I forgot to mention about it, will modify the answer. Thanks for that. – xeco Jun 27 '19 at 06:32
  • @phuclv I was talking about this specific case, but yes, it won't produce 0 when xi>32768. – xeco Jun 27 '19 at 06:38
  • @xeco Thank you for your answer. Can you suggest me a method to overcome this problem caused by the shift? – devHolz Jun 27 '19 at 08:02