В чем разница между интегральным продвижением и балансировкой в ​​C?

Чем отличается интегральная раскрутка от балансировки. Можем ли мы суммировать оба правила, сказав, что любой тип преобразуется по крайней мере в тип int или unsigned int перед выполнением любой операции (кроме логических операторов &&, ||,!) и в больший тип, если какой-либо из операндов имеет тип больше чем инт?


person bubble    schedule 23.08.2012    source источник
comment
Продвижение — это часть C, балансировка — это слово, которое вы только что придумали?   -  person Kerrek SB    schedule 23.08.2012
comment
Что такое балансировка. И как тип может быть больше другого типа? Я не знаю никакого отношения порядка между типами.   -  person Tom Tanner    schedule 23.08.2012
comment
@TomTanner: стандарт C определяет целочисленные ранги преобразования. В C 2011 он находится в 6.3.1.1.   -  person Eric Postpischil    schedule 23.08.2012
comment
@EricPostpischil Это не «высший тип». Вы можете повысить int до float, но он теряет точность   -  person Tom Tanner    schedule 23.08.2012
comment
@TomTanner: Насколько актуален float? Вы написали, что не знаете отношения упорядочивания между типами. Я сообщил вам об отношениях заказа. Учитывая отношение порядка (частичный порядок), некоторые типы «больше», чем некоторые другие типы. Я подозреваю, что под «уравновешиванием» спрашивающий имел в виду «обычные арифметические преобразования» C (6.3.1.8), которые преобразуют несколько операндов в общий тип, используя порядок типов, который включает целочисленный ранг преобразования.   -  person Eric Postpischil    schedule 23.08.2012
comment
@EricPostpischil спасибо за разъяснения. Вы упомянули именно тот раздел, который я имел в виду. Термин «балансировка» использовался в некоторых интерпретациях этого стандарта, таких как MISRA. У меня сложилось впечатление, что это стандартный термин.   -  person bubble    schedule 24.08.2012
comment
Балансировка — довольно распространенный термин программирования, используемый вместо формального термина обычные арифметические преобразования. Почитайте книгу на С, народ...   -  person Lundin    schedule 27.08.2012


Ответы (2)


В стандарте есть две разные вещи, но ни одна из них не называется балансировкой:

Если int может представлять все значения исходного типа (ограниченные шириной для битового поля), значение преобразуется в int; в противном случае он преобразуется в unsigned int. Они называются целочисленными рекламными акциями.58) Все остальные типы не меняются целочисленными рекламными акциями.

....

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

Общая идея для операторов, которые применяются к выражениям другого типа, заключается в том, что операнды преобразуются в тип, в котором потеря точности меньше. Например, если a равно float, а b удвоено, сумма a + b a преобразуется в double перед сложением. Аналогично, если c равно unsigned long, оно сначала преобразуется в double для c + b.

person Jens Gustedt    schedule 23.08.2012
comment
Можно ли привести пример для второго абзаца, не связанного с интегральным продвижением. Думаю, это было бы большим одолжением. - person bubble; 24.08.2012

«Интегральные акции» — это старый термин C90, формальный стандартный термин — целочисленные акции.

Целочисленные продвижения — это правило, которое применяется всякий раз, когда в качестве операнда в выражении используется небольшой целочисленный тип (bool, char, short и их эквиваленты со знаком).

C11 6.3.1.1/4

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

«Балансировка» — это неофициальный термин, обозначающий набор правил, известных как обычные арифметические преобразования. Они определяют, как выполняются все неявные повышения типа каждого операнда в операции. Обратите внимание, что целочисленные акции являются частью обычных арифметических преобразований:

C11 6.3.1.8

Во-первых, если соответствующий реальный тип любого из операндов — long double, другой операнд преобразуется без изменения домена типа в тип, соответствующий вещественный тип которого — long double.

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

В противном случае, если соответствующий вещественный тип любого из операндов — float, другой операнд преобразуется без изменения домена типа в тип, соответствующий вещественный тип которого — float.

В противном случае для обоих операндов выполняются целочисленные преобразования. Затем к повышенным операндам применяются следующие правила:

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

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

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

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

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

person Lundin    schedule 27.08.2012
comment
это относится к c90 или c99 также? - person bubble; 27.08.2012
comment
@bubble C90, C99, C11 и C++ (кроме long double, который, как мне кажется, был введен в C99). Кроме того, я только что узнал, что интегральные продвижения — это старый термин C90, в текущем стандарте они называются целочисленными продвижениями. Сообщение отредактировано. - person Lundin; 27.08.2012