Horrible Answers Galore
Ozgur Ozcitak
Quando você transmite de assinado para não assinado (e vice-versa), a representação interna do número não muda. O que muda é como o compilador interpreta o bit de sinal.
Isso está completamente errado.
Mats Fredriksson
Quando uma variável não assinada e uma assinada são adicionadas (ou qualquer operação binária), ambas são implicitamente convertidas em não assinadas, o que, nesse caso, resultaria em um resultado enorme.
Isso também está errado. As entradas não assinadas podem ser promovidas para entradas, se tiverem precisão igual devido aos bits de preenchimento no tipo não assinado.
smh
Sua operação de adição faz com que o int seja convertido em um int não assinado.
Errado. Talvez sim e talvez não.
A conversão de int não assinado em int assinado é dependente da implementação. (Mas provavelmente funciona da maneira que você espera na maioria das plataformas atualmente.)
Errado. É um comportamento indefinido se causar excesso ou o valor for preservado.
Anônimo
O valor de i é convertido em int não assinado ...
Errado. Depende da precisão de um int em relação a um int não assinado.
Preço de Taylor
Como foi respondido anteriormente, você pode alternar entre assinado e não assinado sem problemas.
Errado. Tentar armazenar um valor fora do intervalo de um número inteiro assinado resulta em um comportamento indefinido.
Agora posso finalmente responder à pergunta.
Se a precisão de int for igual a int sem sinal, u será promovido a um int assinado e você obterá o valor -4444 da expressão (u + i). Agora, se eu e eu tivermos outros valores, você pode ter um comportamento indefinido e indefinido, mas com esses números exatos você obterá -4444 [1] . Este valor terá o tipo int. Mas você está tentando armazenar esse valor em um int não assinado, para que seja convertido em um int não assinado e o valor que o resultado acabará tendo (UINT_MAX + 1) - 4444.
Se a precisão de unsigned int for maior que a de um int, o int assinado será promovido a um int não assinado, produzindo o valor (UINT_MAX + 1) - 5678 que será adicionado ao outro int não assinado 1234. Caso eu e eu tenhamos outros valores, que fazem a expressão ficar fora do intervalo {0..UINT_MAX}, o valor (UINT_MAX + 1) será adicionado ou subtraído até que o resultado fique dentro do intervalo {0..UINT_MAX) e nenhum comportamento indefinido ocorrerá .
O que é precisão?
Os números inteiros têm bits de preenchimento, bits de sinal e bits de valor. Inteiros não assinados não têm um sinal de bit, obviamente. Caracteres não assinados têm ainda a garantia de não ter bits de preenchimento. O número de bits de valores que um número inteiro tem é quanta precisão ele tem.
[Pegadinhas]
O tamanho macro da macro sozinho não pode ser usado para determinar a precisão de um número inteiro se houver bits de preenchimento. E o tamanho de um byte não precisa ser um octeto (oito bits), conforme definido por C99.
[1] O estouro pode ocorrer em um dos dois pontos. Antes da adição (durante a promoção) - quando você tem um int não assinado que é muito grande para caber dentro de um int. O estouro também pode ocorrer após a adição, mesmo que o int não assinado esteja dentro do intervalo de um int, após a adição o resultado ainda pode estourar.