Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Безопасное преобразование между беззнаковым и подписанным int

Автор вопроса: polemicОтветов: 2

У меня есть интерфейс между клиентом и сервером, где клиент отправляет (1) значение без знака и (2) флаг, который указывает, подписано ли значение / нет. Затем сервер будет статически приводить беззнаковое значение к соответствующему типу.

Позже я узнал, что это поведение, определяемое реализацией, и я читал об этом, но не мог найти подходящего решения, которое было бы полностью безопасным? Я читал о каламбурах типов, преобразованиях указателей и memcpy.

Сработает ли просто использование профсоюзного типа? UnionType, содержащий подписанные и неподписанные int, а также флаг подписанный / беззнаковый. Для подписанных значений клиент устанавливает подписанную часть объединения, а сервер читает подписанную часть. То же самое для беззнаковой части. Или я что-то совсем не понимаю?

Дополнительный вопрос: как мне узнать конкретное поведение в этом случае для конкретного сценария, например. windriver diab на ппц? Я немного не понимаю, как найти такую ​​документацию.

  • Если вы не столкнетесь с системой, использующей что-то вроде дополнения или знаковой величины, я думаю, что все, что вы используете, будет определять преобразование без знака в ›знак таким же образом. user2357112 supports Monica 13.06.2014
  • Что должно произойти, когда клиент отправляет беззнаковое значение, но отправляет подписанный флаг? M.M 13.06.2014
  • Также как ваш код обрабатывает подписанный флаг? (поскольку C ++ имеет систему статических типов, вам необходимо назначить свои типы во время компиляции) M.M 13.06.2014
  • @ user2357112, означает ли это, что для систем с двумя дополнениями static_cast ‹int› (static_cast ‹unsigned int› (x)) == x всегда будет верным? polemic 13.06.2014
  • @MattMcNabb, в идеале сервер будет static_cast ‹int› (unsigned_value) и получит ожидаемое значение со знаком. или вы имели в виду случай, когда отправляется тип объединения? подписанный флаг - это просто булево, не уверен, правильно ли я понял ваш второй вопрос - полемика только сейчас отредактируйте polemic 13.06.2014
  • @polemic, который вызывает именно ту проблему, которую вы пытаетесь избежать (поведение, определяемое реализацией), выполняя static_cast ‹int› для беззнакового значения, выходящего за пределы диапазона int. Вы контролируете и клиента, и сервер? M.M 13.06.2014

c++typescastingintunsigned

Ответы

Ответ 1 · M.M

Решение union потребует, чтобы и клиент, и сервер использовали одно и то же представление, что не является хорошей идеей. (например, обе системы с прямым порядком байтов и прямым порядком байтов являются общими).

Вы должны каким-то образом сериализовать значение. Но вы просто делаете это отдельно для каждого типа.

Например (псевдокод)

void send_signed(int32_t x)
{
    send(1, "s");
    send(sizeof x, serialized x);
}

void send_unsigned(uint32_t x)
{
     send(1, "u");
     send(sizeof x, serialized x);
}

И на ресивере; вы сначала читаете шрифт. Если это "s", то вы десериализуете подписанный int и что-то с ним; и если это "u", вы десериализуете беззнаковое int (в другую переменную) и что-то с ним делаете.

Ответ 2 · Cheers and hth. - Alf

Преобразование unsigned int проблематично только формально. На практике все существующие платформы используют представление дополнения до двух, где unsigned int - полная противоположность int unsigned (которая формально четко определена). Так что проблем нет.


Взгляните на статью в Википедии о UNIVAC, чтобы увидеть пример платформы, в которой они дополняют представление был использован, например для 12- и 36-битных слов.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы