¿Por qué se promueven los tipos enteros durante la adición en C?

Entonces tuvimos un problema de campo, y después de días de depuración, redujimos el problema a este bit de código en particular, donde el procesamiento en un ciclo while no estaba sucediendo:

// heavily redacted code
// numberA and numberB are both of uint16_t
// Important stuff happens in that while loop

while ( numberA + 1 == numberB )
{
    // some processing
}

Esto había funcionado bien, hasta que alcanzamos el límite uint16 de 65535. Otro conjunto de declaraciones impresas más tarde, descubrimos quenumberA + 1 tenía un valor de65536, mientrasnumberB envuelto de nuevo a0. Esto falló la verificación y no se realizó ningún procesamiento.

Esto me dio curiosidad, así que armé un programa C rápido (compilado con GCC 4.9.2) para verificar esto:

#include <stdio.h>
#include <stdint.h>

int main()
{

    uint16_t numberA, numberB;
    numberA = 65535;
    numberB = numberA + 1;

    uint32_t numberC, numberD;
    numberC = 4294967295;
    numberD = numberC + 1;

    printf("numberA = %d\n", numberA + 1);
    printf("numberB = %d\n", numberB);

    printf("numberC = %d\n", numberC + 1);
    printf("numberD = %d\n", numberD);

    return 0;
}

Y el resultado fue:

numberA = 65536
numberB = 0
numberC = 0
numberD = 0

Entonces parece que el resultado denumberA + 1 fue promovido a uint32_t. ¿Es esto intencionado por el lenguaje C? ¿O se trata de alguna rareza del compilador / hardware?

Respuestas a la pregunta(4)

Su respuesta a la pregunta