El estándar C11 define el tipo _Bool (6.2.5.2) como un tipo entero estándar sin signo (6.2.5.6) y, según leo el estándar, _Bool también es un tipo aritmético (6.2.5.18 a través de 6.2.5.7 y 6.2.5.17) .
Además, se especifica que para + y - "ambos operandos serán de tipo aritmético, o un operando será un puntero a un tipo de objeto completo y el otro será de tipo entero" (6.5.6.2).
Sin embargo, sobre el resultado solo puedo ver "El resultado del operador binario + es la suma de los operandos" (6.5.6.5) y "El resultado del operador binario - es la diferencia resultante de la resta del segundo operando de el primero" (6.5.6.6). Para dos booleanos, "suma" puede interpretarse como un OR lógico, pero no creo que "resta" tenga un significado bien definido.
Entonces , la pregunta es: ¿el resultado de a+b y ab (donde a y b tienen el tipo _Bool ) es un comportamiento indefinido en C11 o el estándar define claramente el resultado de estas operaciones (si es así, dónde?)?
Nota: tal vez el estándar solo vea _Bool como un número entero con un rango muy pequeño. En ese caso, esperaría que true + true sea 0 (1 + 1 módulo 2). Sin embargo, GCC dice 1 .
Del estándar C (6.5.6 Operadores aditivos)
4 Si ambos operandos tienen tipo aritmético, se realizan sobre ellos las conversiones aritméticas habituales
Y (6.3.1.8 Conversiones aritméticas habituales)
1 Muchos operadores que esperan operandos de tipo aritmético provocan conversiones y producen tipos de resultados de manera similar...
De lo contrario, las promociones de enteros se realizan en ambos operandos .
Y (6.3.1.1 Booleanos, caracteres y enteros)
- ...Si un int puede representar todos los valores del tipo original (restringido por el ancho, para un campo de bits), el valor se convierte en un int; de lo contrario, se convierte en un int sin signo. Estos se llaman las promociones enteras. 58) Todos los demás tipos no se modifican por las promociones enteras .
Entonces, el resultado de una operación aditiva tiene el tipo int cuando ambos operandos tienen el tipo _Bool que son enteros promovidos al tipo int antes de realizar la operación.
Preste atención a que en C no hay un tipo booleano como en C++. El tipo booleano _Bool es un tipo de entero sin signo estándar en C que puede almacenar 1 o 0 .
Así que si vas a escribir por ejemplo
_Bool a = 1; _Bool b = 1; _Bool c = a + b; entonces el valor de la variable c será 1 porque cualquier valor distinto de cero (y el resultado de la operación es el valor 2 del tipo int ) se convierte en 1.
Del estándar C
6.3.1.2 Tipo booleano
1 Cuando cualquier valor escalar se convierte a _Bool, el resultado es 0 si el valor se compara con 0; de lo contrario, el resultado es 1.