Какие наиболее значимые биты устанавливаются при приведении к «более крупному» типу?

В C/С++, когда я выполняю следующее приведение:

uint8_t a = 0xAB;

//In C++
uint32_t b = static_cast<uint32_t>(a);

//In C
uint32_t c = (uint32_t)a;

Я предполагаю, что все старшие значащие биты «большего» типа (b) равны нулю. Гарантируется ли это стандартом при переходе от типа с меньшим количеством бит к типу с большим?

это было бы скорее сломано, если бы приведение к более широкому типу изменило значение. Пожалуйста, выберите один язык

463035818_is_not_a_number 22.02.2023 16:28

Совет: найдите «знак-расширение». И как C, так и C++ не требуют какого-либо конкретного побитового представления целых чисел, поэтому (я полагаю, что могу ошибаться), что установка любых битов в любых стандартных значениях целочисленного типа может быть определена реализацией - мне придется проконсультироваться с спец.

Dai 22.02.2023 16:30

Если бы эти дополнительные биты не были нулями, у вас было бы другое значение.

NathanOliver 22.02.2023 16:32

Дополнительные целые числа 2 (т. е. целые со знаком) будут расширять MSBit, поэтому -1 int8_t по-прежнему будет -1 при назначении int32_t, а не 255.

franji1 22.02.2023 16:33

В зависимости от того, как вы интерпретируете «наиболее значимые биты». Если это реальные биты в памяти, то это будет зависеть от порядка байтов и типа целого числа.

0___________ 22.02.2023 16:33

добавление тега language-lawyer принудительно изменяет объем вопроса и делает недействительными существующие ответы.

463035818_is_not_a_number 22.02.2023 17:04

@ 463035818_is_not_a_number ОП явно хочет, чтобы поведение программы соответствовало стандарту, а не догадкам, как они писали: «Это гарантируется стандартом ...»

Jason Liam 22.02.2023 17:05

@JasonLiam тег языкового юриста обычно означает больше. Без тега «Да, это гарантировано» может быть хорошим ответом. Добавление тега делает недействительными уже существующие ответы.

463035818_is_not_a_number 22.02.2023 17:07

@JasonLiam One спрашивает, «что происходит». Другой спрашивает «главу и стих стандарта, что должно / разрешено происходить». Две разные вещи.

DevSolar 22.02.2023 17:07

@ 463035818_is_not_a_number Нет, просто сказать «да или нет» — это не ответ. Нужно также показать, почему именно так обстоит дело в соответствии со стандартом, если OP специально задал вопрос о поведении в соответствии со стандартом.

Jason Liam 22.02.2023 17:08

@DevSolar Нет, явное указание «глава и стих» не является обязательным. Некоторые вещи являются неявными и имеют здравый смысл. Если человек говорит, что стандарт говорит то или иное, то он должен показать, где это сказано, пока вопрос задавался для того и в этом случае он был задан.

Jason Liam 22.02.2023 17:09

@JasonLiam «да» или «нет» — это ответ на вопрос «а?». ТС, я с тобой не спорю. Я просто пытаюсь донести свою точку зрения до модов, которые, как я надеюсь, решат эту бессмысленную войну правок.

463035818_is_not_a_number 22.02.2023 17:09

@ 463035818_is_not_a_number Ясно, я думаю, что тег language-lawyer также сделает (в дополнение к этому) этот вопрос (и его ответы) более каноническим, чтобы будущие читатели могли непосредственно видеть поведение программы точно так, как это предписано стандартом.

Jason Liam 22.02.2023 17:13

@JasonLiam, вы не обязаны пытаться сделать вопрос «более каноничным». Кроме того, неправильно пытаться сделать это, когда это делает недействительными существующие ответы.

John Bollinger 22.02.2023 17:15

@JasonLiam из описания тега «Используйте этот тег для вопросов, когда вас интересует формальная спецификация для определенного поведения на данном языке программирования [...]», нет никаких доказательств того, что это то, чего хочет здесь ОП, они действительно просто задают простой вопрос да/нет

463035818_is_not_a_number 22.02.2023 17:17
xkcd.com/1167
leosch 22.02.2023 17:23

@ 463035818_is_not_a_number Как я уже сказал, SO — это больше, чем сайт вопросов MCQ. Просто писать «правда или ложь» не является целью сайта. Люди, отвечающие на вопрос, должны объяснить (если ОП прямо задал вопрос, как в этом вопросе в моем понимании), цитируя соответствующие ссылки из стандарта. Но я тоже могу ошибаться.

Jason Liam 22.02.2023 17:23
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
17
105
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Тип 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. Это называется «расширением знака».

Другие вопросы по теме