Por que os tipos inteiros são promovidos durante a adição em C?
Então, tivemos um problema de campo e, após dias de depuração, reduzimos o problema a esse bit específico de código, onde o processamento em um loop while não estava acontecendo:
// heavily redacted code
// numberA and numberB are both of uint16_t
// Important stuff happens in that while loop
while ( numberA + 1 == numberB )
{
// some processing
}
Isso funcionou bem, até atingirmos o limite uint16 de 65535. Outro monte de instruções impressas posteriormente, descobrimos quenumberA + 1
teve um valor de65536
, enquantonumberB
embrulhado de volta para0
. Isso falhou na verificação e nenhum processamento foi concluído.
Isso me deixou curioso, então montei um programa C rápido (compilado com o GCC 4.9.2) para verificar isso:
#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;
}
E o resultado foi:
numberA = 65536
numberB = 0
numberC = 0
numberD = 0
Portanto, parece que o resultado denumberA + 1
foi promovido para uint32_t. Isso é pretendido pela linguagem C? Ou isso é uma raridade do compilador / hardware?