В C/С++, когда я выполняю следующее приведение:
uint8_t a = 0xAB;
//In C++
uint32_t b = static_cast<uint32_t>(a);
//In C
uint32_t c = (uint32_t)a;
Я предполагаю, что все старшие значащие биты «большего» типа (b
) равны нулю. Гарантируется ли это стандартом при переходе от типа с меньшим количеством бит к типу с большим?
Совет: найдите «знак-расширение». И как C, так и C++ не требуют какого-либо конкретного побитового представления целых чисел, поэтому (я полагаю, что могу ошибаться), что установка любых битов в любых стандартных значениях целочисленного типа может быть определена реализацией - мне придется проконсультироваться с спец.
Если бы эти дополнительные биты не были нулями, у вас было бы другое значение.
Дополнительные целые числа 2 (т. е. целые со знаком) будут расширять MSBit, поэтому -1 int8_t по-прежнему будет -1 при назначении int32_t, а не 255.
В зависимости от того, как вы интерпретируете «наиболее значимые биты». Если это реальные биты в памяти, то это будет зависеть от порядка байтов и типа целого числа.
добавление тега language-lawyer
принудительно изменяет объем вопроса и делает недействительными существующие ответы.
@ 463035818_is_not_a_number ОП явно хочет, чтобы поведение программы соответствовало стандарту, а не догадкам, как они писали: «Это гарантируется стандартом ...»
@JasonLiam тег языкового юриста обычно означает больше. Без тега «Да, это гарантировано» может быть хорошим ответом. Добавление тега делает недействительными уже существующие ответы.
@JasonLiam One спрашивает, «что происходит». Другой спрашивает «главу и стих стандарта, что должно / разрешено происходить». Две разные вещи.
@ 463035818_is_not_a_number Нет, просто сказать «да или нет» — это не ответ. Нужно также показать, почему именно так обстоит дело в соответствии со стандартом, если OP специально задал вопрос о поведении в соответствии со стандартом.
@DevSolar Нет, явное указание «глава и стих» не является обязательным. Некоторые вещи являются неявными и имеют здравый смысл. Если человек говорит, что стандарт говорит то или иное, то он должен показать, где это сказано, пока вопрос задавался для того и в этом случае он был задан.
@JasonLiam «да» или «нет» — это ответ на вопрос «а?». ТС, я с тобой не спорю. Я просто пытаюсь донести свою точку зрения до модов, которые, как я надеюсь, решат эту бессмысленную войну правок.
@ 463035818_is_not_a_number Ясно, я думаю, что тег language-lawyer также сделает (в дополнение к этому) этот вопрос (и его ответы) более каноническим, чтобы будущие читатели могли непосредственно видеть поведение программы точно так, как это предписано стандартом.
@JasonLiam, вы не обязаны пытаться сделать вопрос «более каноничным». Кроме того, неправильно пытаться сделать это, когда это делает недействительными существующие ответы.
@JasonLiam из описания тега «Используйте этот тег для вопросов, когда вас интересует формальная спецификация для определенного поведения на данном языке программирования [...]», нет никаких доказательств того, что это то, чего хочет здесь ОП, они действительно просто задают простой вопрос да/нет
@ 463035818_is_not_a_number Как я уже сказал, SO — это больше, чем сайт вопросов MCQ. Просто писать «правда или ложь» не является целью сайта. Люди, отвечающие на вопрос, должны объяснить (если ОП прямо задал вопрос, как в этом вопросе в моем понимании), цитируя соответствующие ссылки из стандарта. Но я тоже могу ошибаться.
Тип uint8_t
— беззнаковый целочисленный тип.
uint8_t a = 0xAB;
Таким образом, значение будет сохранено, когда объект этого типа будет приведен к типу uint32_t
, потому что объекты этого типа могут вмещать значение 0xAB
.
На самом деле кастинг излишен. Вы можете просто написать
uint32_t c = a;
Вы даже можете написать
uint32_t a = 0xAB;
uint8_t c = a;
потому что снова значение 0xAB
может быть сохранено в объекте типа uint8_t
.
Техническая терминология C и C++ в этой области немного различается. Я буду использовать терминологию C, но изложенные идеи применимы к обоим языкам.
Преобразования типов, такие как приведения типов в стиле C и C++ static_cast
, являются операциями над значениями, а не над объектами, и их результаты также являются значениями, а не объектами. Представления значений операнда и результата, включая значения любых конкретных битов, не рассматриваются в спецификациях для этих операций.
Таким образом, основной ответ на ваш вопрос заключается в том, что при применении к значениям арифметического типа эти операции сохраняют значение, если целевой тип может представлять значение операнда.
Что касается вашего примера, вы спрашиваете...
Я предполагаю, что все старшие значащие биты «большего» типа (b) равны нулю. Гарантируется ли это стандартом при переходе от типа с меньшим количеством бит к типу с большим?
В свете (отдельных) спецификаций для представления целочисленных типов преобразование является средством сохранения значения.
Для неотрицательных операндов, если исходный и целевой типы являются целыми типами, а целевой тип представлен большим количеством битов значения, чем исходный тип, то биты значения представления результата целевого типа, которые не соответствуют биты значения в исходном представлении значения операнда примут значение 0.
Для отрицательных операндов, если исходный и целевой типы являются целочисленными типами (со знаком), а целевой тип представлен в форме дополнения до двух с большим количеством битов значения, чем исходный тип, то биты значения представления типа назначения результата которые не соответствуют битам значения в исходном представлении операнда, примут значение 1. Это называется «расширением знака».
это было бы скорее сломано, если бы приведение к более широкому типу изменило значение. Пожалуйста, выберите один язык