¿Es bool un tipo C nativo?

265

Me di cuenta de que el código del kernel de Linux usa bool, pero pensé que bool era un tipo C ++. ¿Bool es una extensión C estándar (por ejemplo, ISO C90) o una extensión GCC?

asussex
fuente
2
La Sección 9 de las preguntas frecuentes de comp.lang.c discute esto.
Keith Thompson
1
Enlace directo: c-faq.com/bool/index.html
Ellen Spertus
El kernel de Linux utiliza -std=gnu89que admite _Boolcomo una extensión de C90. "include / linux / types.h" tiene typedef _Bool bool;.
Ian Abbott
Además, FWIW, el kernel de Linux 2.6.19 fue la primera versión en usar typedef _Bool bool;(commit 6e21828743247270d09a86756a0c11702500dbfb ) y requería GNU C 3.2 o posterior.
Ian Abbott

Respuestas:

368

bool existe en el C - C99 actual, pero no en C89 / 90.

En C99, el tipo nativo se llama realmente _Bool, mientras que booles una macro de biblioteca estándar definida en stdbool.h(que se espera que se resuelva _Bool). Objetos de tipo _Boolde retención 0 o 1, mientras que truey falseson también las macros de stdbool.h.

Tenga en cuenta, por cierto, que esto implica que el preprocesador C interpretará #if truecomo a #if 0menos que stdbool.hesté incluido. Mientras tanto, se requiere el preprocesador de C ++ para reconocer de forma nativa truecomo un lenguaje literal.

Hormiga
fuente
62
Hay un nuevo estándar ISO C, publicado en 2011 (después de que se publicó esta respuesta). ANSI, como de costumbre, ha adoptado el estándar ISO C11 como estándar ANSI. Por razones históricas, la frase "ANSI C" comúnmente (pero de manera incorregible) se refiere al lenguaje definido por el estándar ANSI C89 / ISO C90. Dado que las normas C ahora son publicadas por ISO primero, y dado que ha habido tres normas ISO C, con diferentes niveles de adopción, es mejor referirse al año en que se publicó la norma (ISO C90, ISO C99, ISO C11) para evitar confusión.
Keith Thompson
8
¿Esto significa que _Boolocupa 1 bit de memoria?
Geremia
27
@Geremia: No. ¿Por qué? En C cada objeto direccionable tiene que ocupar al menos 1 byte. Y en la vida real, las implementaciones _Boolgeneralmente requieren 1 byte de memoria. Sin embargo, la especificación del lenguaje permite explícitamente el uso _Boolcomo tipo de campo de bits, lo que significa que al usar campos de bits puede exprimir un _Boolvalor en un solo bit (dentro de una estructura más grande).
AnT
@AnT ¿Cómo podría un _Boolvalor ser directamente direccionable (es decir, de tamaño 1 byte) y también participar en un campo de bits? Una matriz de _Booltodavía requeriría que todos sus elementos sean direccionables (por ejemplo _Bool* ptr = &boolArray[123]).
Dai
118

C99 agregó un _Booltipo de datos incorporado (consulte Wikipedia para más detalles), y si lo hace #include <stdbool.h>, se proporciona boolcomo una macro para _Bool.

Preguntaste sobre el kernel de Linux en particular. Asume la presencia de _Booly proporciona un booltypedef en sí mismo en include / linux / types.h .

Josh Kelley
fuente
26
En cuanto a por qué, es para permitir que sea indefinido y redefinido donde su definición pueda causar un choque con el código heredado.
Clifford el
32

No, no existe boolen ISO C90.

Aquí hay una lista de palabras clave en el estándar C (no C99):

  • auto
  • break
  • case
  • char
  • const
  • continue
  • default
  • do
  • double
  • else
  • enum
  • extern
  • float
  • for
  • goto
  • if
  • int
  • long
  • register
  • return
  • short
  • signed
  • static
  • struct
  • switch
  • typedef
  • union
  • unsigned
  • void
  • volatile
  • while

Aquí hay un artículo que discute algunas otras diferencias con C como se usa en el núcleo y el estándar: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html

BobbyShaftoe
fuente
66
Para fines prácticos, ¿realmente importa mientras no exista un soporte decente para el compilador? Incluso gcc no tenía la mitad de las características de C99 hasta hace poco, y MSVC no tiene la mayoría de ellas, y probablemente nunca las tendrá ...
Pavel Minaev
55
@Jonathan Leffler, el interlocutor preguntó específicamente sobre ISO C90. :) De hecho, por lo general, cuando las personas se refieren a ANSI C, responden a C90. No uso o realmente planeo usar C99 y creo que muchos sienten lo mismo.
BobbyShaftoe
66
@BobbyShaftoe: El póster original decía explícitamente en un comentario que C90 era un ejemplo.
Keith Thompson
32

C99 lo tiene en stdbool.h , pero en C90 debe definirse como typedef o enum:

typedef int bool;
#define TRUE  1
#define FALSE 0

bool f = FALSE;
if (f) { ... }

Alternativamente:

typedef enum { FALSE, TRUE } boolean;

boolean b = FALSE;
if (b) { ... }
Robar
fuente
55
Tenga en cuenta que el comportamiento del typedef será diferente al del C99 bool, y también diferente al de muchos bittipos de compiladores . Por ejemplo, bool x=4294967296LL;o bool x=0.1;se establecería xen uno en C99, pero probablemente establecería la mayoría de las versiones typedef en cero.
supercat
17
/* Many years ago, when the earth was still cooling, we used this: */

typedef enum
{
    false = ( 1 == 0 ),
    true = ( ! false )
} bool;

/* It has always worked for me. */
usuario2705144
fuente
16
Los valores iniciales son completamente innecesarios. typedef enum { false, true };es igual de bueno Si insiste en ser más explícito, puede escribir typedef enum { false = 0, true = 1 };. (O simplemente #include <stdbool.h>si su compilador lo admite; ha sido estándar durante 14 años.)
Keith Thompson
9
@KeithThompson Los valores iniciales pueden ser innecesarios, pero esta respuesta los elige de una manera muy elegante, no con valores arbitrarios, sino usando la propia semántica de los lenguajes y dejando que el compilador decida.
MestreLion
11
@MestreLion: la propia semántica del lenguaje garantiza que typedef enum { false, true } bool;funciona exactamente como se esperaba. 1 == 0y ! falseno son elegantes, simplemente están ofuscados. No hay una decisión que tome el compilador; debe obedecer la semántica definida por el lenguaje.
Keith Thompson
11
@KeithThompson: No creo que estén ofuscados, supongo que la intención del autor fue elegir los valores más "naturales": falsese establece en cualquier valor que el lenguaje dice que se debe evaluar una desigualdad, y trueen su "opuesto" ( de nuevo, sea lo que sea). De esta manera, no debería importarnos si eso es {1, 0}, {-1, 0}, {0, 1}, etc., y se garantiza que funcionará en las comparaciones, ya que se creó utilizando uno.
MestreLion
3
@MestreLion: Cualquiera que conozca C conoce los valores numéricos de falsey true. Cualquiera que no conozca C no es la audiencia esperada para el código C. Y como dije, C ha tenido un tipo booleano incorporado desde el milenio anterior.
Keith Thompson
12

_Booles una palabra clave en C99: especifica un tipo, al igual que into double.

6.5.2

2 Un objeto declarado como tipo _Bool es lo suficientemente grande como para almacenar los valores 0 y 1.

pmg
fuente
6

C99 define bool, truey falseen stdbool.h.

starblue
fuente
1

stdbool.h define macros verdadero y falso, pero recuerde que se define como 1 y 0.

Por eso sizeof(true)es 4.

Neha Gangwar
fuente
0

No existe tal cosa, probablemente solo una macro para int

sindre j
fuente
Agradable con -1 ... la pregunta era C90, no 99, creo
Sindre j
55
bueno, dice C estándar, por ejemplo , C90, supongo que incluye C99.
Matt Joiner
2
Menciona C90 específicamente, NO C99, así que supongo que lo que quiere decir. Según Wikipedia, el único compilador que es totalmente compatible con C99 es Sun Studio de Sun Microsystems. Ahora, eso no es un estándar ampliamente aceptado, ¿verdad? Posiblemente la mayoría de los compiladores modernos implementan partes del estándar C99, ¡probablemente debería haber mencionado eso para evitar comentarios estúpidos como el suyo! ¿Qué tiene que ver Java o C # con este BTW?
sindre j
8
La extensión estándar C (por ejemplo, ISO C90) está clasificando el tipo de estándares C que le interesan, no específicamente el propio C90. una respuesta apropiada a esto es, si una norma como C90 C, específicamente el estándar C99, no implementar un booltipo.
Matt Joiner
0

C99 agregó un booltipo cuya semántica es fundamentalmente diferente de la de casi todos los tipos enteros que existieron anteriormente en C, incluidos los tipos definidos por el usuario y la extensión del compilador destinados a tales fines, y que algunos programas pueden tener "type-def" ed a bool.

Por ejemplo, dado bool a = 0.1, b=2, c=255, d=256;, el booltipo C99 establecería los cuatro objetos en 1. Si se usara un programa C89 typedef unsigned char bool, los objetos recibirían 0, 1, 255 y 0, respectivamente. Si se usa char, los valores pueden ser como se indica arriba o c-1. Si hubiera utilizado una extensión bito __bittipo de compilador , los resultados probablemente serían 0, 0, 1, 0 (tratando bitde forma equivalente a un campo de bits sin signo de tamaño 1, o un tipo entero sin signo con un bit de valor).

Super gato
fuente