Definiciones extrañas de macros VERDADERAS y FALSAS
He visto las siguientes definiciones de macros en un libro de codificación.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Allí no hubo ninguna explicación.
Por favor explíqueme cómo funcionarán como TRUE
y FALSE
.
Veamos: '/' / '/'
significa el char
literal /
, dividido por el char
literal '/'
mismo. El resultado es uno que parece razonable TRUE
.
Y '-' - '-'
significa lo char
literal '-'
, sustraído de sí mismo. Esto es cero ( FALSE
).
Hay dos problemas con esto: primero, no es legible. Usar 1
y 0
es absolutamente mejor. Además, como han señalado TartanLlama y KerrekSB, si alguna vez va a utilizar esa definición, agregue paréntesis alrededor de ella para no tener sorpresas:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
Esto imprimirá el valor del char
literal '-'
(45 en mi sistema).
Entre paréntesis:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
el programa imprime correctamente cero, aunque no tiene mucho sentido multiplicar un valor de verdad por un número entero, pero es sólo un ejemplo del tipo de errores inesperados que podrían afectarle si no pone entre paréntesis sus macros.
Es solo otra forma de escribir
#define TRUE 1
#define FALSE 0
La expresión '/'/'/'
dividirá el valor del carácter '/'
por sí mismo, lo que dará como resultado 1.
La expresión '-'-'-'
restará el valor char de '-'
sí misma, lo que dará como resultado 0.
Sin embargo, faltan corchetes alrededor de las define
expresiones completas, lo que puede provocar errores en el código al utilizar estas macros. La respuesta de Jay aborda eso bastante bien.
Un ejemplo de escenario de la "vida real" donde olvidar los corchetes puede ser perjudicial es el uso combinado de estas macros con un operador de conversión estilo C. Si alguien decide convertir estas expresiones en bool
C++, por ejemplo:
#include <iostream>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
std::cout << "True: " << (bool) TRUE << std::endl;
std::cout << "False: " << (bool) FALSE << std::endl;
return 0;
}
Esto es lo que obtenemos:
True: 0
False: -44
Entonces (bool) TRUE
realmente evaluaría a false
y (bool) FALSE
evaluaría a true
.
Equivale a escribir
#define TRUE 1
#define FALSE 0
Lo que realmente hace la expresión '/'/'/'
es dividir el carácter /
(cualquiera que sea su valor numérico) por sí mismo, por lo que se convierte en 1
.
De manera similar, la expresión '-'-'-'
resta el carácter -
de sí misma y se evalúa como 0
.
Sería mejor escribir
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
para evitar cambios accidentales de valores cuando se usa con otros operadores de mayor prioridad.