Я боюсь, что у меня может быть что-то тривиальное, но, похоже, нет реального безопасного способа конвертировать в/из подписанного типа, если вы хотите сохранить исходное значение без знака.Нет совместимого способа конвертировать подписанные/неподписанные одинаковые размеры
В reinterpret_cast 5.2.10 не перечисляет целочисленное целочисленное преобразование, поэтому оно не определено (и static_cast не определяет дополнительного преобразования). При интегральных преобразованиях 4.7.3 в основном говорят, что преобразование большого без знака будет реализовано (поэтому не переносимо).
Это кажется ограниченным, поскольку мы знаем, например, что uint64_t
должен на любом оборудовании быть надежно конвертируемым в int64_t
и обратно без изменения стоимости. Кроме того, правила стандартных типов макета фактически гарантируют безопасное преобразование, если мы должны были memcpy
между двумя типами вместо назначения.
Правильно ли я? Существует ли законная причина, по которой невозможно достичь reinterpret_cast
между целыми типами достаточного размера?
Разъяснение: Определенно подписанная версия без знака не гарантируется значение, но только туда-обратно, что я рассматриваю (без знака => подписаны => беззнаковое)
ОБНОВЛЕНИЕ: Внимательно изучая ответы и перекрестно проверяя стандарт, я считаю, что на самом деле не гарантировано работать memcpy
, поскольку нигде он не говорит о том, что эти два типа совместимы с макетом, и ни один из них не является типом символов. Дальнейшее обновление, копание в C-стандарте, этот memcpy должен работать, поскольку размер цели достаточно велик и копирует байты.
ОТВЕТ: Там, кажется, не будет никаких технических причин, почему reinterpret_cast не было разрешено выполнять это преобразование. Для этих фиксированных размеров целочисленных типов гарантируется работа memcpy
, и действительно, до тех пор, пока промежуточный элемент может представлять все битовые шаблоны, может использоваться любой промежуточный тип (float может быть опасным, поскольку могут быть шаблоны ловушек). В общем случае вы не можете memcpy между любыми стандартными типами макета, они должны быть совместимыми или типами символов. Здесь специальные функции, поскольку у них есть дополнительные гарантии.
Я думаю, что вы всегда можете это сделать, ведь с помощью reinterpret_cast вы просто говорите компилятору, как интерпретировать местоположение памяти, не изменяя значение местоположения. –
«на любом оборудовании». Именно в этом и есть смысл. Возможно, на любом оборудовании, с которым вы могли бы работать, но C++ не предназначен для академических целей для поддержки некоторых других вещей, кроме дополнения 2-го, а потому, что на самом деле такое оборудование. И (u) типы intXX_t просто обязаны вести себя в вычислениях «как-если» они были дополнением к 2-м, нет требования, что аппаратное обеспечение должно быть. – PlasmaHH
@PlasmaHH, я хочу сказать, что 'uint64_t',' int64_t' - это точный размер (если поддерживается на оборудовании), и, таким образом, гарантируется, что «memcpy» будет конвертировать (по правилам стандартных типов макета). Мне все равно, что здесь есть 2 дополнения, я хочу конвертировать назад и вперед. –