Duas armadilhas comuns usando int não assinado

Normalmente, é uma boa ideia usar um não assinado em vez de um int regular para representar um número natural. Isso torna o programa mais eficiente, dobra o intervalo da variável e torna a intenção do programador mais clara.
No entanto, existem duas armadilhas comuns com essa abordagem:

Se houver uma expressão envolvendo inteiros assinados e não assinados, os inteiros assinados serão promovidos a não assinados :

unsigned int x = 1;
int y = -2;
(x + y > 0) ? puts("WRONG ANSWER") : puts("CORRECT ANSWER"); //Output: WRONG ANSWER

Loops onde a variável de controle é um inteiro sem sinal podem facilmente se tornar loops infinitos.

for(unsigned z = 5; z >= 0; z--){doSomething(z);}  // Infinite Loop

O problema acima às vezes está presente mesmo se não declararmos nenhuma variável sem sinal, caso em que é mais difícil de detectar. No exemplo abaixo, o tamanho da string não tem sinal, o que torna a expressão à direita negativa, que é convertida em um grande valor positivo.

const int lengthLimit = 10;
const std::string example = "EXAMPLE";
int index = 0;
while(++index < example.size() - lengthLimit){doSomething();} //A LOT of iterations

O remédio mais fácil é mover as variáveis ​​de um lado da comparação para o outro, de modo que sempre tenhamos acréscimos quando houver pelo menos uma variável sem sinal na expressão:

const int lengthLimit = 10;
const std::string example = "EXAMPLE";
int index = 0;
while(++index + lengthLimit < example.size()){doSomething();} //No iterations