Hoy, mientras escribía un código de Visual C ++, me encontré con algo que me sorprendió. Parece que C ++ admite ++ (incremento) para bool, pero no - (decremento). ¿Es solo una decisión aleatoria o hay alguna razón detrás de esto?
Esto compila:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
Esto no lo hace:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
++once
yonce++
trabaja con gcc, pero no con los decrementos.bool
preincremento para está obsoleto, souce .std::exchange(once,false)
(nota: no atómico), si desea algo que no esté obsoleto.Respuestas:
Proviene de la historia del uso de valores enteros como booleanos.
Si
x
es anint
, pero lo estoy usando como booleano según,if(x)...
entonces incrementar significará que cualquiera que sea su valor de verdad antes de la operación, tendrá un valor de verdad detrue
después de ella (salvo desbordamiento).Sin embargo, es imposible predecir el resultado de
--
un conocimiento dado solo del valor de verdad dex
, ya que podría resultar enfalse
(si el valor integral es 1) otrue
(si el valor integral es cualquier otra cosa, en particular, esto incluye 0 [false
] y 2 o más [true
]).Entonces, como taquigrafía
++
funcionó, y--
no lo hizo.++
está permitido en bools por compatibilidad con esto, pero su uso está desaprobado en el estándar.Esto supone que solo lo uso
x
como booleano, lo que significa que el desbordamiento no puede ocurrir hasta que lo haya hecho con la++
frecuencia suficiente para causar un desbordamiento por sí mismo. Incluso con char como el tipo usado yCHAR_BITS
algo bajo como 5, eso es 32 veces antes de que esto ya no funcione (ese sigue siendo un argumento suficiente para que sea una mala práctica, no estoy defendiendo la práctica, solo explicando por qué funciona) para 32 bitsint
, por supuesto, tendríamos que usar++
2 ^ 32 veces antes de que esto sea un problema. Con--
aunque sólo resultará enfalse
si comenzaba con un valor de 1 paratrue
, o se inicia con 0 y se utiliza++
, precisamente, una vez antes.Esto es diferente si comenzamos con un valor que está solo unos pocos por debajo de 0. De hecho, en tal caso, podríamos querer
++
dar como resultado elfalse
valor eventualmente, como en:Sin embargo, este ejemplo se trata
x
como enint
todas partes excepto el condicional, por lo que es equivalente a:Lo cual es diferente a usar solo
x
como booleano.fuente
<limits.h>
encabezado y laCHAR_BIT
macro. Antes de eso, supongo que teóricamente podría haber habido implementaciones en las quechar
es más estrecho que 8 bits, pero hasta donde yo sé, no hubo ninguna. En particular, K & R1 (publicado en 1978) enumera 4 implementaciones de muestra, todas las cuales tienen 8 bits o 9 bitschar
.CHAR_BIT >= 8
. El estándar no hace concesiones para los objetivos donde eso es difícil. (Podría tener una implementación no conforme, por supuesto.)ANSI ISO IEC 14882 2003 (c ++ 03):
5.2.6-2
Y como era de esperar ...
5.3.2-2
Además, 5.6.2-1 y 5.3.2-1 mencionan que ++ para bools debe ser verdadero y el Anexo D-1 dice que ++ en bools está desaprobado.
fuente
Esto fue apoyado por razones históricas. Pero tenga en cuenta que ... El uso de un operando de tipo bool con el operador ++ está en desuso, consulte la Sección 5.3.2 en el estándar C ++ (n3092)
5.3.2 Incremento y decremento [expr.pre.incr]
fuente
fuente