¿Por qué el tipo booleano en C ++ admite ++ pero no -?


29

¿Por qué el operador --no existe para bool mientras que sí existe para el operador ++?

Lo intenté en C ++, y no sé si mi pregunta se aplica a otro idioma. Estaré encantado de saber también.

Lo sé , puedo usar el operador ++con un bool. Hace que cualquier bool sea igual a verdadero.

bool b = false;
b++;
// Now b == true.

¿Por qué no podemos usar el operador --de manera opuesta?

bool b = true;
b--;
// Now b == false;

No es muy útil, pero tengo curiosidad.


8
Esta pregunta sobre StackOverflow puede ser esclarecedora.
Blrfl

Entonces la razón de la historia. Gracias por el enlace. ¿Puedes escribir una respuesta y la pongo como resuelta?
aloisdg dice Reinstate Monica

Los enlaces por sí solos no son buenas respuestas, y no hay un buen mecanismo para marcar esta pregunta como un duplicado de algo en otro sitio de SE.
Blrfl

1
Entonces deberíamos abrir un tema en meta.stackexchange.com o algo así. Creo que deberías obtener algo de karma para el buen enlace y si alguien te vota, el autor de la respuesta original debería obtener algo de karma. De hecho, la pregunta original también debería tener algo de karma.
aloisdg dice Reinstate Monica

2
Los duplicados de sitios cruzados de @aloisdg son un problema antiguo en MSO. Persiga las preguntas vinculadas para obtener una visión más completa.

Respuestas:


53

En los viejos tiempos de C, no había tipo booleano. La gente usaba el intpara almacenar datos booleanos, y funcionaba principalmente. Zero era falso y todo lo demás era cierto.

Esto significaba que si tomabas int flag = 0;y luego lo hacías , flag++el valor sería verdadero. Esto funcionaría sin importar cuál fuera el valor de la marca (a menos que lo hicieras mucho, se volcó y volviste a cero, pero ignoremos eso) : el incremento de la bandera cuando su valor era 1 daría 2, que todavía era cierto.

Algunas personas usaron esto para establecer incondicionalmente un valor booleano en verdadero. No estoy seguro de que alguna vez se haya vuelto idiomático , pero está en algún código.

Esto nunca funcionó --, porque si el valor fuera distinto de 1 (que podría ser), el valor aún no sería falso. Y si ya era falso ( 0) e hiciste un operador de decremento, no sería falso.

Al mover el código de C a C ++ en los primeros días, era muy importante que el código C incluido en C ++ todavía pudiera funcionar. Y así, en la especificación para C ++ (sección 5.2.6 (está en la página 71)) se lee:

El valor obtenido al aplicar un postfix ++ es el valor que tenía el operando antes de aplicar el operador. [Nota: el valor obtenido es una copia del valor original] El operando será un valor modificable. El tipo del operando será un tipo aritmético o un puntero a un tipo de objeto completo. Después de anotar el resultado, el valor del objeto se modifica agregando 1, a menos que el objeto sea de tipo bool, en cuyo caso se establece en verdadero. [Nota: este uso está en desuso, ver anexo D.]

El operando de postfix - se decrementa de manera análoga al operador postfix ++, excepto que el operando no será de tipo bool.

Esto se menciona nuevamente en la sección 5.3.2 (para el operador de prefijo - 5.2.6 estaba en postfix)

Como puede ver, esto está en desuso (Anexo D en el documento, página 709) y no debe usarse.

Pero por eso. Y a veces puedes ver el código. Pero no lo hagas.


55
"Algunas personas usaron esto para establecer incondicionalmente un valor booleano en verdadero". Llamémoslos malditos tontos, no personas.
Deduplicador

@Deduplicator: Tal vez fue una cuestión de rendimiento: cargar un valor en una variable puede haber tomado más ciclos de procesador que incrementar la variable. Por supuesto, esto probablemente no importa en las computadoras modernas.
Giorgio

1
@Giorgio que es bastante probable. Recuerde que C fue escrito para coincidir estrechamente con el conjunto de instrucciones PDP-7 y el PDP-11 tenía otros ajustes. A partir de esto : "La gente a menudo adivina que fueron creados para usar los modos de dirección de incremento automático y decremento automático proporcionados por DEC PDP-11 en el que C y Unix se hicieron populares por primera vez. Esto es históricamente imposible, ya que no había PDP- 11 cuando se desarrolló B. El PDP-7, sin embargo, tenía algunas celdas de memoria de "auto-incremento", con la propiedad de que una referencia indirecta de memoria a través de ellas incrementaba la celda ".

@Deduplicator: en el código que usa números enteros para booleanos, una variable que se incrementa para cada ... lo que sea ... puede actuar como un contador (cuántas veces se incrementó) y como un booleano (se ha incrementado en absoluto o no).
Keith Thompson el


1

Para comprender el significado histórico de esta pregunta, debe considerar el caso de Therac-25. El Therac-25 era un dispositivo médico que administraba radiación a pacientes con cáncer. Estaba plagado de malas prácticas de programación que contribuyeron a su pobre historial de seguridad (con múltiples muertes atribuidas).

http://courses.cs.vt.edu/professionalism/Therac_25/Therac_1.html

(vaya al final de la página 3)

Cada pasada a través de la rutina de prueba de configuración incrementa la verificación de la posición del colimador superior, una variable compartida llamada Class3. Si la clase 3 no es cero, existe una inconsistencia y el tratamiento no debe continuar. Un valor cero para la Clase 3 indica que los parámetros relevantes son consistentes con el tratamiento y que el haz no está inhibido.

...

Durante la configuración de la máquina, la Prueba de configuración se ejecutará varios cientos de veces, ya que se reprogramará a la espera de que ocurran otros eventos. En el código, la variable Class3 se incrementa en uno en cada pasada a través de la Prueba de configuración. Como la variable Class3 es de 1 byte, solo puede contener un valor máximo de 255 decimales. Por lo tanto, en cada paso 256 a través del código de prueba de configuración, la variable se desborda y tiene un valor cero. Eso significa que en cada 256º paso a través de la Prueba de configuración, el colimador superior no se verificará y no se detectará una falla del colimador superior. La sobreexposición se produjo cuando el operador presionó el botón "establecer" en el momento preciso en que la Clase3 pasó a cero. Por lo tanto, Chkcol no se ejecutó y F $ mal no se configuró para indicar que el colimador superior todavía estaba en posición de luz de campo. El software activó los 25 MeV completos sin el objetivo en su lugar y sin escanear. Se produjo un haz de electrones altamente concentrado, que fue dispersado y desviado por el espejo de acero inoxidable que se encontraba en el camino.

Therac-25 usó algo como el equivalente de operator++en a bool. Sin embargo, el lenguaje de programación que usaron no era C ++, y su tipo de datos no lo era bool. Sin embargo, a diferencia de la garantía en C ++, un tipo entero normal simplemente sigue subiendo. Su tipo de datos era el equivalente de uint8_t.

C ++ decidió mantener el operator++margen para las personas acostumbradas a programar de esta manera, pero en lugar de aumentar el valor, simplemente lo configura truepara evitar cosas como esta.

Tenga en cuenta que operator++(bool)está en desuso.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf

Anexo D de C ++ 14:

D.1 Operador de incremento con operando bool
El uso de un operando de tipo bool con el operador ++ está en desuso (ver 5.3.2 y 5.2.6).


Si bien eso explicaría por qué está en desuso, no explica por qué existe en primer lugar.

Existe porque hubo algunas personas que establecieron un valor booleano incrementándolo al programar en C. C ++ fue diseñado para facilitar la transición de C, por lo que lo apoyaron con el booltipo. Solo estaba tratando de dar un ejemplo histórico de cuándo las personas realmente programaban de esta manera.
David Stone
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.