Несовместимый способ преобразования подписанного / неподписанного одинакового размера

Боюсь, что я могу упустить что-то тривиальное, но похоже, что нет надежного способа преобразования в / из подписанного типа, если вы хотите сохранить исходное значение без знака.

В reinterpret_cast 5.2.10 не перечисляется преобразование целого числа в целое число, поэтому оно не определено (и static_cast не определяет дополнительное преобразование). Об интегральных преобразованиях 4.7.3 в основном говорит, что преобразование большого числа без знака будет определяться реализацией (таким образом, не переносимо).

Это кажется ограничивающим, поскольку мы знаем, например, что uint64_t на любом оборудовании должен быть безопасно преобразован в int64_t и обратно без изменения значения. Кроме того, правила для стандартных типов макетов фактически гарантируют безопасное преобразование, если бы мы использовали memcpy между двумя типами вместо assign.

Я прав? Есть ли законная причина, по которой нельзя reinterpret_cast между целочисленными типами достаточного размера?


Уточнение: определенно подписанная версия unsigned не гарантирует значение, но это только круговой обход, который я учитывая (unsigned => signed => unsigned)


ОБНОВЛЕНИЕ : При внимательном рассмотрении ответов и перекрестной проверки стандарта я считаю, что memcpy на самом деле не гарантированно работает, поскольку нигде не в нем указано, что эти два типа совместимы с макетом, и ни один из них не является типом char. Дальнейшее обновление, копание в C-стандарте, этот memcpy должен работать, так как размер цели достаточно велик, и он копирует байты.


ОТВЕТ : Похоже, нет никакой технической причины, по которой reinterpret_cast не было разрешено выполнить это преобразование. Для этих целочисленных типов фиксированного размера memcpy гарантированно работает, и действительно, пока промежуточное звено может представлять все битовые шаблоны, можно использовать любой промежуточный тип (float может быть опасным, поскольку могут быть шаблоны ловушек) . В общем, вы не можете использовать memcpy между любыми стандартными типами макетов, они должны быть совместимыми или типами char. Здесь инты особенные, так как на них есть дополнительные гарантии.

7
задан edA-qa mort-ora-y 28 February 2012 в 07:15
поделиться