Обычные арифметические преобразования в C: каково обоснование этого конкретного правила - PullRequest
1 голос
/ 20 января 2012

Из k & R C

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

Это означало бы, что приведенное ниже выражение

char a,b,c;

c=a+b;

фактически помечено как

c = char((int)a+(int)b);

Что является обоснованием этого правила?

Эти преобразования происходят, если a, b и c были короткими?

Ответы [ 3 ]

3 голосов
/ 20 января 2012

Нет, это не совсем так.C99 Раздел 5.1.2.3 Program execution, пункт 10 охватывает точно случай, о котором вы спрашиваете:

ПРИМЕР 2
При выполнении фрагмента
char c1, c2;
c1 = c1 + c2;
«целочисленные продвижения» требуют, чтобы абстрактная машина повышала значение каждой переменной до размера int, а затем добавляла два целых числа и усекала сумму.

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

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

Но если вы хотите обосновать конкретное решение, принятое в стандарте, вам нужно посмотреть, ..... подождать, ....да, Обоснование документа : -)

В разделе 6.3.1.8 этого обоснования (разделы соответствуют тем в стандарте), оно гласит:

Явный лиcense был добавлен для выполнения вычислений в «более широком» типе, чем это абсолютно необходимо, поскольку иногда это может привести к созданию меньшего и более быстрого кода, не говоря уже о правильном ответе.

Вычисления также можно выполнять в «более узком»”, Как правило, если получен тот же конечный результат.

2 голосов
/ 20 января 2012

Некоторые архитектуры набора команд не имеют каких-либо арифметических машинных инструкций для работы с целыми числами меньше слова (например, short и char). Поэтому требование этого соглашения упрощает работу компилятора. И в большинстве случаев достаточно преобразования в слово и операндов размером с слово.

0 голосов
/ 20 января 2012

Происходят ли эти преобразования, если a, b и c были короткими?

Да, целочисленные продвижения выполняются для всех типов малых целых чисел: char, short и C99 bool.

Строго говоря, программа на C не может выполнять какую-либо арифметику с чем-либо меньшим, чем int, если компилятор не оптимизирует целочисленные преобразования.

...