Посмотрите мой тестовый код:
#include <stdlib.h>
#include <stdio.h>
#define PRINT_COMPARE_RESULT(a, b) \
if (a > b) { \
printf( #a " > " #b "\n"); \
} \
else if (a < b) { \
printf( #a " < " #b "\n"); \
} \
else { \
printf( #a " = " #b "\n" ); \
}
int main()
{
signed int a = -1;
unsigned int b = 2;
signed short c = -1;
unsigned short d = 2;
PRINT_COMPARE_RESULT(a,b);
PRINT_COMPARE_RESULT(c,d);
return 0;
}
В результате получается следующее:
a > b
c < d
Моя платформа - Linux, а моя версия gcc - 4.4.2. Меня удивляет вторая линия вывода. Первая строка вывода вызвана целым продвижением. Но почему результат второй линии отличается?
Следующие правила относятся к стандарту C99:
Если оба операнда имеют один и тот же тип, то дальнейшее преобразование не требуется. В противном случае, если оба операнда имеют целочисленные типы или оба имеют unsigned целочисленных типов, операнд с типом меньшего целочисленного ранга преобразования преобразуется в тип операнда с большим рангом.
В противном случае, если операнд с целым типом без знака имеет ранг больше или равный рангам типа другого операнда, то операнд с целочисленный тип со знаком преобразуется в тип операнда без знака целочисленный тип.
В противном случае, если тип операнда со знаком целочисленного типа может представлять все значения типа операнда с целым типом без знака, тогда операнд с целым числом без знака преобразуется в тип операнд со знаковым целым типом.
В противном случае оба операнда преобразуются в целочисленный тип без знака соответствующий типу операнда со знаком целочисленного типа.
Я думаю, что оба этих сравнения должны принадлежать одному и тому же случаю, второй случай целочисленного продвижения.