2016-12-07 1 views
4

Я быстро просмотрел стандарт C++ 03, но до сих пор не может сказать, если это поведение гарантировано:Standard C++ Поведение Signed Чары беззнакового Int Conversion

signed char cNegOne=-1; //char is 8bits 
unsigned int a=cNegOne; //int is 32 bits in my Windows system 
printf("0x%x\n",a); 

результата:

0xffffffff 

VC++ дает 0xffffffff в 32-битной Windows. Но мое предположение состоит в том, что преобразование может произойти двумя способами:

1) 8-разрядный подписанный символ -1 сначала преобразуется непосредственно в 8-разрядное значение без знака, которое является двоичным 11111111 или десятичным числом 255, которое затем расширилось до 32- бит unsigned int, дающий 255 (0xff).

2) 8-разрядный подписанный символ -1 подписывается расширенным до 32-битного подписанного значения int, дающего 0xffffffff, а затем переинтерпретируется как 32-разрядный беззнаковый int.

Очевидно, что здесь используется второй способ. Но почему это так? В стандарте я ничего не могу сказать об этом. Это конкретная реализация?

EDIT: оригинальный текст из C++ 03 Глава 4

Стандартные преобразования неявные преобразования, определенные для встроенных типов. В пункте 4 перечисляется полный набор таких преобразований. Стандартная последовательность преобразования представляет собой последовательность стандартных преобразований в следующем порядке:

- Нулевое или одно преобразование из следующего набора: преобразование lvalue-to-rval, преобразование матрицы в указатель и преобразование функции в указатель ,

- Нулевое или одно преобразование из следующего набора: интегральные промо-акции, продвижение с плавающей запятой, интегральные преобразования, конверсии с плавающей запятой, конверсии с плавающей точкой, конверсии указателей, указатели на членские преобразования и логические преобразования.

- Zero или один квалификация изменение.

Обратите внимание, что гарантированный заказ - это преобразование значения l в rvalue (и т. Д.) Происходит до того, как будут установлены интегральные рекламные акции/конверсии, но это не означает, что перед конверсиями должны произойти интегральные проработки - они находятся в одном наборе. Или моя интерпретация правильная?

+0

Вы не можете промотировать, и преобразование происходит в одной и той же стандартной последовательности преобразования («ноль» или один "). 'char' to' unsigned int' является одним интегральным преобразованием. –

ответ

4

При выполнении целочисленной арифметики в C и C++ самым первым шагом является целая продвижение. подписанные символы и шорты становятся подписанными; unsigned chars и shorts становятся беззнаковыми ints. Это правда, даже если вы, скажем, добавляете два шорта вместе: сама операция выполняется на ints, а не на шортах.

Итак, когда вы думаете о преобразовании целых чисел, подумайте с точки зрения продвижения по службе, а затем измените подпись. В стандарте C++ эти два этапа описываются как один. То есть отдельная интегральная реклама технически не происходит, но эффект изменения подписанности, если тип назначения шире, чем тип источника, идентичен тому, что происходило бы, если явное продвижение предшествовало изменению подписи. Основное правило состоит в том, что результатом должен быть вход по модулю 2^n, где n - количество бит выходного типа. Для ввода -1 и 32-битного выходного типа это означает, что выходной сигнал 2^32 - 1.

+0

см. Мое редактирование.Действительно ли стандарт гарантирует продвижение по службе до конверсий? – JavaMan

+0

@JavaMan Я думаю, я смущенно объяснил это. Я отредактирую. – Sneftel