Преобразование 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]
будет полезно.