Acompanhando as listas do comp.lang.c, vi um código que estava relacionado a promoção de tipos em C. O seguinte código:
unsigned char c = 128;
print("~c=%d.\n", ~c);
c = 128 = 0x80 . Negando esse valor, temos ~c= 0x7F=127. Tão logo você compile e execute este código, a
saída será:
~c=-129.
O que houve? A resposta é o título deste post: "integer promotion". Por incrível que pareça, a variável c foi convertida para um inteiro antes de se aplicar o operador complemento. Dessa forma, temos que ~c = ~(int)c. Em sequência:
c -> 128 (0xF0) -> (int) 0x000000F0 -> ~ 0xFFFFFF7F ou 0xFF7F=129, se o inteiro for de 16-bits. Estranho não é? Mais estranho ainda é a solução para o código:
unsigned char c = 128;
c=~c;
print("~c=%d.\n", c);
Nessa expressão, não ocorre a promoção de tipo inteiro, pois a variável que receberá o valor é um de 8 bits. Porque alguém vai querer inventar um operador que muda o tipo da em que opera?
Eu mesmo utilizei o operador complemento para macros de cálculo de variação de tempo:
elapsed = now >= last ? now - last: (~0) - last + now + 1;
Provavelmente funciona porque o tipo de variável elapsed é de 32-bits.