Рассмотрим следующий пример:
#include <stdio.h>
int main(void)
{
    unsigned char a  = 15; /* one byte */
    unsigned short b = 15; /* two bytes */
    unsigned int c   = 15; /* four bytes */
    long x = -a; /* eight bytes */
    printf("%ld\n", x);
    x = -b;
    printf("%ld\n", x);
    x = -c;
    printf("%ld\n", x);
    return 0;
}
Для компиляции я использую GCC 4.4.7 (и это не давало мне никаких предупреждений):
gcc -g -std=c99 -pedantic-errors -Wall -W check.c
Мой результат:
-15
-15
4294967281
Вопрос в том, почему значения unsigned char и unsigned short "правильно распространяются" (подписаны) long, а unsigned int - нет? Есть ли какая-либо ссылка или правило на этом?
Вот результаты от gdb (слова в порядке младшего порядка):
(gdb) x/2w &x
0x7fffffffe168: 11111111111111111111111111110001    11111111111111111111111111111111 
(gdb) x/2w &x
0x7fffffffe168: 11111111111111111111111111110001    00000000000000000000000000000000
