Арифметическое преобразование VS интегральное продвижение

char cval;
short sval;
long lval;
sval + cval; // sval and cval promoted to int
cval + lval; // cval converted to long

Это фрагмент кода на C ++ Primer. Я знаю, что sval+cval генерирует тип int в соответствии с

преобразовать малые целочисленные типы в более крупные целочисленные типы. Типы bool, char, signed char, unsigned char, short и unsigned short повышаются до int, если все возможные значения этого типа подходят для int.

Но для последнего я не мог понять, почему он использует "преобразованный". Почему cval сначала не повышается до int, а затем int конвертируется (или, может быть, повышается, я не уверен, можно ли использовать повышение с int до long, потому что я вижу определение повышения только для меньшего шрифта до int) до long. Я не видел никаких объяснений или примеров на char прямо к long в этой части книги.
Что-то не так с моим пониманием?
Я новичок в C ++, пожалуйста, просветите меня! Спасибо заранее!


person Des1gnWizard    schedule 28.12.2015    source источник


Ответы (2)


Аддитивные операторы выполняют то, что называется обычным арифметическим преобразованием своих операндов, которые может включать в себя интегральные рекламные акции, а затем, после этого, у нас могут быть дальнейшие преобразования. Цель состоит в том, чтобы получить общий тип, и если рекламные акции не достигают этого, требуется дальнейшее преобразование.

Это описано в разделе 5 [expr] чернового варианта стандарта C ++, в котором говорится (выделено мной):

Многие бинарные операторы, которые ожидают операндов арифметического или перечислительного типа, вызывают преобразования и выдают типы результатов аналогичным образом. Цель состоит в том, чтобы получить общий тип, который также является типом результата. Этот шаблон называется обычным арифметическим преобразованием, который определяется следующим образом

и включает в себя следующий пункт:

  • В противном случае интегральные предложения (4.5) будут выполнены для обоих операндов.61 Затем к продвинутым операндам будут применяться следующие правила:

который имеет следующие пули:

  • Если оба операнда имеют один и тот же тип, дальнейшее преобразование не требуется

  • В противном случае, если оба операнда имеют целочисленные типы со знаком или оба имеют целочисленные типы без знака, операнд с типом меньшего целочисленного ранга преобразования должен быть преобразован в тип операнда с большим рангом .

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

Таким образом, в первом случае после рекламных акций они имеют один и тот же тип (int), поэтому дальнейшее преобразование не требуется.

Во втором случае после рекламных акций они не работают (int и long), поэтому требуется дальнейшее преобразование.

person Shafik Yaghmour    schedule 28.12.2015
comment
Спасибо за старания! - person Des1gnWizard; 28.12.2015

Из стандарта C ++ 11:

4 стандартных преобразования

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

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

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

- Ноль или одно преобразование квалификации.

В выражении

cval + lval;

поскольку cval не относится к типу long, его необходимо преобразовать в long. Однако в процессе применения стандартных преобразований интегральное продвижение опережает преобразования. Следовательно, cval сначала повышается до int перед преобразованием в long.

person R Sahu    schedule 28.12.2015