Преобразование long-endian long в C++?

Мне нужна функция C++, которая возвращает значение четырех последовательных байтов, интерпретируемых как бигендовская длина. Указатель на первый байт должен быть обновлен, чтобы указывать после последнего. Я пробовал следующий код:

inline int32_t bigendianlong(unsigned char * &p)  
{  
  return (((int32_t)*p++ << 8 | *p++) << 8 | *p++) << 8 | *p++;  
}  

Например, если p указывает на 00 00 00 A0, я ожидаю, что результат будет 160, но это 0. Как получится?

2 ответа

Решение

Проблема ясно объясняется этим предупреждением (выданным компилятором):

./endian.cpp:23:25: warning: multiple unsequenced modifications to 'p' [-Wunsequenced]
    return (((int32_t)*p++ << 8 | *p++) << 8 | *p++) << 8 | *p++;

Разбиваем логику в функции, чтобы явно указать точки последовательности...

inline int32_t bigendianlong(unsigned char * &p)
{
    int32_t result = *p++;
    result = (result << 8) + *p++;
    result = (result << 8) + *p++;
    result = (result << 8) + *p++;
    return result;
}

... решит это

Эта функция называется ntohl() (преобразовать байтовый порядок сети в длинный хост) в Unix и Windows, или g_ntohl() в бой Добавьте 4 к вашему указателю позже. Если вы хотите бросить свой собственный, тип профсоюза, члены которого являются uint32_t и uint8_t[4] будет полезно.

Другие вопросы по тегам