Hoje, ao escrever algum código Visual C ++, encontrei algo que me surpreendeu. Parece que C ++ suporta ++ (incremento) para bool, mas não - (decremento). É apenas uma decisão aleatória ou há algum motivo por trás disso?
Isso compila:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
Isso não:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
++once
eonce++
trabalhar com gcc, mas não com decrementos.bool
é preterido, souce .std::exchange(once,false)
(nota: não atômico), se você quiser algo não obsoleto.Respostas:
Ele vem da história do uso de valores inteiros como booleanos.
Se
x
for umint
, mas estou usando-o como um booleano,if(x)...
então incrementar significará que qualquer que seja o seu valor verdade antes da operação, terá um valor verdadetrue
depois (barrando o estouro).No entanto, é impossível prever o resultado de
--
determinado conhecimento apenas do valor de verdade dex
, já que poderia resultar emfalse
(se o valor integral for 1) outrue
(se o valor integral for qualquer outra coisa - notavelmente isso inclui 0 [false
] e 2 ou mais [true
]).Então, como um atalho
++
funcionou, e--
não funcionou .++
é permitido em bools para compatibilidade com isso, mas seu uso está obsoleto no padrão.Isso pressupõe que eu use apenas
x
como booleano, o que significa que o estouro não pode acontecer até que eu tenha feito o++
suficiente para causar um estouro por conta própria. Mesmo com char como o tipo usado eCHAR_BITS
algo baixo como 5, isso é 32 vezes antes que isso não funcione mais (isso ainda é um argumento suficiente para ser uma prática ruim, não estou defendendo a prática, apenas explicando por que funciona) para 32 bits,int
é claro que teríamos de usar++
2 ^ 32 vezes antes que isso fosse um problema. Com--
embora, ele só resultará emfalse
se eu começar com um valor de 1 paratrue
, ou começar com 0 e usar++
precisamente uma vez antes.Isso é diferente se começarmos com um valor que é apenas alguns abaixo de 0. Na verdade, nesse caso, podemos querer
++
resultar nofalse
valor eventualmente, como em:No entanto, este exemplo trata
x
como umint
todo, exceto o condicional, portanto, é equivalente a:O que é diferente de usar apenas
x
como booleano.fonte
<limits.h>
cabeçalho e aCHAR_BIT
macro. Antes disso, suponho que teoricamente poderia ter havido implementações ondechar
é mais estreito do que 8 bits, mas até onde eu sei não havia nenhuma. Em particular, K & R1 (publicado em 1978) lista 4 exemplos de implementação, todos com 8 ou 9 bitschar
.CHAR_BIT >= 8
. O padrão não permite alvos onde isso é difícil. (Você poderia ter uma implementação não conforme, é claro.)ANSI ISO IEC 14882 2003 (c ++ 03):
5.2.6-2
E sem surpresa ...
5.3.2-2
Além disso, 5.6.2-1 e 5.3.2-1 mencionam que ++ para bools deve ser verdadeiro e o Anexo D-1 diz que ++ para bools está obsoleto.
fonte
Por razões históricas, isso foi apoiado. Mas observe que ... O uso de um operando do tipo bool com o operador ++ está obsoleto, consulte a Seção 5.3.2 no Padrão C ++ (n3092)
5.3.2 Incremento e decremento [expr.pre.incr]
fonte
fonte