Bool è un tipo C nativo?


265

Ho notato che il codice del kernel Linux usa bool, ma ho pensato che bool fosse di tipo C ++. Bool è un'estensione C standard (ad es. ISO C90) o un'estensione GCC?


2
La sezione 9 delle FAQ di comp.lang.c ne discute.
Keith Thompson,


Il kernel di Linux utilizza -std=gnu89quali supporti _Boolcome estensione per C90. "include / linux / types.h" ha typedef _Bool bool;.
Ian Abbott,

Inoltre, FWIW, il kernel 2.6.19 di Linux è stata la prima versione da utilizzare typedef _Bool bool;(commit 6e21828743247270d09a86756a0c11702500dbfb ) e richiedeva GNU C 3.2 o versione successiva.
Ian Abbott,

Risposte:


368

bool esiste nell'attuale C - C99, ma non in C89 / 90.

In C99 viene effettivamente chiamato il tipo nativo _Bool, mentre boolè definita una macro di libreria standard in stdbool.h(che si prevede si risolva in _Bool). Gli oggetti di tipo _Boolcontengono 0 o 1, mentre sono truee falsesono anche macro stdbool.h.

Nota, a proposito, ciò implica che il preprocessore C interpreterà #if truecome #if 0se non stdbool.hfosse incluso. Nel frattempo, è richiesto il preprocessore C ++ per riconoscere nativamente truecome linguaggio letterale.


62
C'è un nuovo standard ISO C, pubblicato nel 2011 (dopo che questa risposta è stata pubblicata). ANSI, come al solito, ha adottato lo standard ISO C11 come standard ANSI. Per motivi storici, la frase "ANSI C" comunemente (ma in modo errato) si riferisce al linguaggio definito dalla norma ANSI C89 / ISO C90. Dal momento che gli standard C sono ora pubblicati da ISO prima e poiché ci sono stati tre standard ISO C, con vari livelli di adozione, è meglio fare riferimento all'anno in cui lo standard è stato pubblicato (ISO C90, ISO C99, ISO C11) per evitare qualsiasi confusione.
Keith Thompson,

8
Questo significa che _Booloccupa 1 bit di memoria?
Geremia,

27
@Geremia: No. Perché? In C ogni oggetto indirizzabile deve occupare almeno 1 byte. E nella vita reale le implementazioni di _Boolsolito richiedono 1 byte di memoria. Tuttavia, la specifica del linguaggio consente esplicitamente l'utilizzo _Boolcome tipo di campo di bit, il che significa che utilizzando i campi di bit è possibile comprimere un _Boolvalore in un singolo bit (all'interno di una struttura più grande).
AnT

@AnT In che modo un _Boolvalore può essere sia indirizzabile direttamente (ovvero dimensione 1 byte) e anche partecipare a un campo bit? Un array di _Boolrichiederebbe comunque che tutti i suoi elementi siano indirizzabili (ad es _Bool* ptr = &boolArray[123].).
Dai,

118

C99 ha aggiunto un _Booltipo di dati incorporato (vedere Wikipedia per i dettagli) e, se disponibile #include <stdbool.h>, fornisce booluna macro a _Bool.

Hai chiesto informazioni sul kernel Linux in particolare. Presuppone la presenza _Boole fornisce un booltypedef stesso in include / linux / types.h .


26
Per quanto riguarda il motivo, è per consentire che non sia definito e ridefinito dove la sua definizione potrebbe causare uno scontro con il codice legacy.
Clifford,

32

No, non esiste boolISO C90.

Ecco un elenco di parole chiave nella norma C (non 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

Ecco un articolo che discute alcune altre differenze con C come usato nel kernel e nello standard: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html


6
Ai fini pratici, importa davvero finché non esiste ancora un supporto decente per il compilatore? Anche gcc non aveva la metà delle funzionalità di C99 fino a poco tempo fa, e MSVC non ne ha la maggior parte, e probabilmente non lo farà mai ...
Pavel Minaev,

5
@Jonathan Leffler, l'interrogatore ha chiesto specificamente riguardo all'ISO C90. :) In effetti, di solito quando le persone si riferiscono ad ANSI C hanno C90. Non uso o non intendo davvero usare C99 e penso che molti la pensino allo stesso modo.
BobbyShaftoe,

6
@BobbyShaftoe: il poster originale diceva esplicitamente in un commento che C90 era un esempio.
Keith Thompson,

32

C99 lo ha in stdbool.h , ma in C90 deve essere definito come typedef o enum:

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

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

In alternativa:

typedef enum { FALSE, TRUE } boolean;

boolean b = FALSE;
if (b) { ... }

5
Si noti che il comportamento del typedef sarà diverso da quello del C99 boole anche diverso da quello di molti bittipi di compilatori . Ad esempio, bool x=4294967296LL;o bool x=0.1;impostarebbe xuno su C99, ma probabilmente imposterebbe la maggior parte delle versioni typedef su zero.
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. */

16
I valori iniziali sono del tutto inutili. typedef enum { false, true };è altrettanto buono. Se insisti per essere più esplicito, puoi scrivere typedef enum { false = 0, true = 1 };. (O solo #include <stdbool.h>se il tuo compilatore lo supporta; è stato standard per 14 anni.)
Keith Thompson,

9
@KeithThompson I valori iniziali potrebbero non essere necessari, ma questa risposta li sceglie in modo molto elegante, non con valori arbitrari, ma utilizzando la semantica delle lingue e lasciando decidere al compilatore.
MestreLion,

11
@MestreLion: la garanzia semantica della lingua che typedef enum { false, true } bool;funziona esattamente come previsto. 1 == 0e ! falsenon sono eleganti, sono semplicemente offuscati. Non c'è alcuna decisione da prendere per il compilatore; deve obbedire alla semantica definita dalla lingua.
Keith Thompson,

11
@KeithThompson: non credo che siano offuscati, immagino che l'intenzione dell'autore fosse quella di scegliere i valori più "naturali": falseè impostato su qualunque valore il linguaggio dice che dovrebbe essere valutata una disuguaglianza e trueal suo "opposto" ( di nuovo, qualunque cosa sia). In questo modo non ci si dovrebbe preoccupare se questo è {1, 0}, {-1, 0}, {0, 1}, ecc. Ed è garantito che funzioni a confronto, perché è stato realizzato usando uno.
MestreLion,

3
@MestreLion: Chiunque conosca C conosce i valori numerici di falsee true. Chi non conosce C non è il pubblico previsto per il codice C. E come ho detto, C ha avuto un tipo booleano incorporato dal millennio precedente.
Keith Thompson,

12

_Boolè una parola chiave in C99: specifica un tipo, proprio come into double.

6.5.2

2 Un oggetto dichiarato come tipo _Bool è abbastanza grande da memorizzare i valori 0 e 1.




1

stdbool.h definisce le macro true e false, ma ricorda che è definito come 1 e 0.

Ecco perché sizeof(true)è 4.


0

Niente del genere, probabilmente solo una macro per int


Bello con -1's ... la domanda era C90, non 99 credo
sindre j

5
bene dice lo standard C es. C90, suppongo che includa C99.
Matt Joiner

2
Parla in modo particolare di C90, NON di C99, quindi presumo che cosa significhi. Secondo Wikipedia l'unico compilatore che supporta pienamente C99 è Sun Studio di Sun Microsystems. Ora, questo non è uno standard ampiamente accettato, vero? Probabilmente la maggior parte dei compilatori moderni implementa parti dello standard C99, probabilmente avrei dovuto dirlo per evitare stupidi commenti come il tuo! Cosa c'entra java o c # con questo BTW?
maggio

8
l'estensione C standard (ad es. ISO C90) sta classificando il tipo di standard C a cui è interessato, non specificamente C90 stesso. una risposta adeguata a questa è, un C standard come C90, in particolare lo standard C99, non attuare un booltipo.
Matt Joiner,

0

C99 ha aggiunto un booltipo la cui semantica è sostanzialmente diversa da quella di quasi tutti i tipi di numeri interi che erano esistiti in precedenza in C, inclusi i tipi definiti dall'utente e l'estensione del compilatore destinati a tali scopi e che alcuni programmi potrebbero avere "type-def" ed a bool.

Ad esempio, dato bool a = 0.1, b=2, c=255, d=256;, il booltipo C99 imposterebbe tutti e quattro gli oggetti su 1. Se si utilizza un programma C89 typedef unsigned char bool, gli oggetti riceveranno rispettivamente 0, 1, 255 e 0. Se utilizzato char, i valori potrebbero essere come sopra o cpotrebbero essere -1. Se avesse utilizzato un'estensione bito un __bittipo di compilatore , i risultati sarebbero probabilmente 0, 0, 1, 0 (trattando bitin modo equivalente a un campo bit senza segno di dimensioni 1 o un tipo intero senza segno con un bit di valore).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.