С++ конвертирует char[] из сети в порядок хоста и назначает беззнаковое целое число

У меня есть массив символов в сетевом порядке байтов. Я пытаюсь преобразовать символы, хранящиеся в индексах [4-7], в порядок хоста и назначить его беззнаковому целому числу. У меня есть следующая функция:

unsigned int parse_num_bytes(char buf[]){ 
  unsigned int num_bytes = ((unsigned int)buf[7] << 24) | ((unsigned int)buf[6] << 16) | ((unsigned int)buf[5] << 8) | (unsigned int)buf[4];
  return num_bytes;
}

Из GDB (на самом деле LLDB, потому что я на Mac) я вижу, что операция генерирует правильный результат, но после присваивания значение неверно:

   81
   82   unsigned int parse_num_bytes(char buf[]){
   83     unsigned int num_bytes = ((unsigned int)buf[7] << 24) | ((unsigned int)buf[6] << 16) | ((unsigned int)buf[5] << 8) | (unsigned int)buf[4];
-> 84     return num_bytes;
   85   }
(lldb) p num_bytes
(unsigned int) $0 = 4294967170
(lldb) p ((unsigned int)buf[7] << 24) | ((unsigned int)buf[6] << 16) | ((unsigned int)buf[5] << 8) | (unsigned int)buf[4]
(unsigned int) $1 = 2434

Для уточнения, 2434 является правильным значением.

Здесь я генерирую сетевой порядок (в серверном приложении):

return_buf[4] = index & 0xff;
return_buf[5] = (index >> 8) & 0xff;
return_buf[6] = (index >> 16) & 0xff;
return_buf[7] = (index >> 24) & 0xff;

И из GDB я могу показать вам значение индекса (это unsigned int)

   142    return_buf[4] = index & 0xff;
   143    return_buf[5] = (index >> 8) & 0xff;
   144    return_buf[6] = (index >> 16) & 0xff;
-> 145    return_buf[7] = (index >> 24) & 0xff;
   146
   147    in_file.close();
   148    Rio_writen(connfd, return_buf, MAXLINE);
(lldb) p index
(unsigned int) $0 = 2434

person Kendall Weihe    schedule 30.11.2016    source источник


Ответы (1)


Предположим, ваш тип char подписан, поэтому он может содержать отрицательные значения. Они плохо конвертируются в unsigned int.

Возможно, вы захотите использовать unsigned char для вашего типа буфера.

person Bo Persson    schedule 30.11.2016