Являются ли «обычные арифметические преобразования» и «целочисленные продвижения» одинаковыми? Я читал, что «обычные арифметические преобразования» используются, чтобы сделать операнды выражения одного типа, в то время как «целочисленные продвижения» используются для продвижения типов, меньших, чем int
в int
, но в MSDN оба эти понятия относятся только к «обычным арифметическим преобразованиям».
Нет.
обычные арифметические преобразования подразумевают интегральное продвижение при определенных обстоятельствах, но это два отдельных механизма:
[C++14: 5/10]:
Многие бинарные операторы, которые ожидают операнды арифметического или перечислимого типа, вызывают преобразования и выдают типы результатов аналогичным образом. Цель состоит в том, чтобы получить общий тип, который также является типом результата. Эта модель называется обычные арифметические преобразования, которые определены следующим образом:
- Если какой-либо из операндов имеет тип перечисления с ограничением (7.2), преобразования не выполняются; если другой операнд не имеет того же типа, выражение неправильно сформировано.
- Если один из операндов имеет тип
long double
другой должен быть преобразован вlong double
,- В противном случае, если любой из операндов
double
другой должен быть преобразован вdouble
,- В противном случае, если любой из операндов
float
другой должен быть преобразован вfloat
,- В противном случае выполняются интегральные продвижения (4.5). на обоих операндах.61 Затем к повышенным операндам применяются следующие правила:
- Если оба операнда имеют одинаковый тип, дальнейшее преобразование не требуется.
- В противном случае, если оба операнда имеют целочисленные типы со знаком или оба имеют целочисленные типы без знака, операнд с типом ранга преобразования с меньшим целым числом должен быть преобразован в тип операнда с большим рангом.
- В противном случае, если операнд с целочисленным типом без знака имеет ранг больше или равен рангу типа другого операнда, операнд с целочисленным типом со знаком должен быть преобразован в тип операнда с целочисленным типом без знака.
- В противном случае, если тип операнда с целочисленным типом со знаком может представлять все значения типа операнда с целочисленным типом без знака, операнд с целочисленным типом без знака должен быть преобразован в тип операнда с целочисленным типом со знаком.
- В противном случае оба операнда должны быть преобразованы в тип целого без знака, соответствующий типу операнда с целым типом со знаком.
Формулировка почти такая же в C11.
Обратите внимание, что интегральные продвижения могут также выполняться при обстоятельствах, которые не имеют ничего общего с обычными арифметическими преобразованиями, например операнд LHS битового сдвига; в конечном счете, все это — то, почему у этих двух механизмов есть свои отличные имена!