Le bool est-il un type C natif?

265

J'ai remarqué que le code du noyau Linux utilise bool, mais je pensais que bool était un type C ++. Bool est-il une extension C standard (par exemple, ISO C90) ou une extension GCC?

asussex
la source
2
La section 9 de la FAQ comp.lang.c en parle.
Keith Thompson
1
Lien direct: c-faq.com/bool/index.html
Ellen Spertus
Le noyau Linux utilise -std=gnu89ce qui prend _Boolen charge comme une extension de C90. "include / linux / types.h" a typedef _Bool bool;.
Ian Abbott
De plus, FWIW, le noyau Linux 2.6.19 a été la première version à utiliser typedef _Bool bool;(commit 6e21828743247270d09a86756a0c11702500dbfb ) et il nécessitait GNU C 3.2 ou une version ultérieure.
Ian Abbott

Réponses:

368

bool existe dans le C - C99 actuel, mais pas dans le C89 / 90.

En C99, le type natif est en fait appelé _Bool, tandis boolqu'une macro de bibliothèque standard est définie dans stdbool.h(qui se résout normalement _Bool). Les objets de type _Boolcontiennent 0 ou 1, tandis que trueet falsesont également des macros de stdbool.h.

Notez, BTW, que cela implique que le préprocesseur C interprétera #if truecomme #if 0sauf s'il stdbool.hest inclus. Pendant ce temps, le préprocesseur C ++ est nécessaire pour reconnaître nativement truecomme un littéral de langage.

Fourmi
la source
62
Il y a une nouvelle norme ISO C, publiée en 2011 (après la publication de cette réponse). L'ANSI, comme d'habitude, a adopté la norme ISO C11 comme norme ANSI. Pour des raisons historiques, l'expression "ANSI C" fait couramment (mais de façon incorrecte) référence au langage défini par la norme ANSI C89 / ISO C90. Étant donné que les normes C sont désormais publiées par l'ISO en premier et qu'il existe trois normes ISO C, avec différents niveaux d'adoption, il est préférable de se référer à l'année de publication de la norme (ISO C90, ISO C99, ISO C11) pour éviter toute confusion.
Keith Thompson
8
Est-ce à dire que cela _Boolprend 1 bit de mémoire?
Geremia
27
@Geremia: Non. Pourquoi? En C, chaque objet adressable doit occuper au moins 1 octet. Et dans la réalité, les implémentations _Boolprennent généralement 1 octet de mémoire. Cependant, la spécification du langage autorise explicitement l'utilisation _Boolcomme type de champ de bits, ce qui signifie qu'en utilisant des champs de bits, vous pouvez compresser une _Boolvaleur en un seul bit (à l'intérieur d'une structure plus grande).
AnT
@AnT Comment une _Boolvaleur peut-elle être à la fois directement adressable (c'est-à-dire de taille 1 octet) et également participer à un champ binaire? Un tableau de _Boolnécessiterait toujours que tous ses éléments soient adressables (par exemple _Bool* ptr = &boolArray[123]).
Dai
118

C99 a ajouté un _Booltype de données intégré (voir Wikipedia pour plus de détails), et si vous #include <stdbool.h>, il fournit boolune macro à _Bool.

Vous avez posé des questions sur le noyau Linux en particulier. Il suppose la présence de _Boolet fournit un booltypedef lui-même dans include / linux / types.h .

Josh Kelley
la source
26
Quant à savoir pourquoi, c'est de permettre qu'il ne soit pas défini et redéfini là où sa définition pourrait provoquer un conflit avec le code hérité.
Clifford
32

Non, il n'y boolen a pas dans ISO C90.

Voici une liste de mots clés en C standard (pas 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

Voici un article discutant d' autres différences avec C telles qu'utilisées dans le noyau et la norme: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html

BobbyShaftoe
la source
6
À des fins pratiques, est-ce vraiment important tant qu'il n'y a toujours pas de support de compilateur décent? Même gcc n'avait pas la moitié des fonctionnalités de C99 jusqu'à récemment, et MSVC n'en a pas la plupart, et ne le fera probablement jamais ...
Pavel Minaev
5
@Jonathan Leffler, l'intervenant a spécifiquement posé des questions sur l'ISO C90. :) En fait, généralement lorsque les gens se réfèrent à l'ANSI C, ils mesurent le C90. Je n'utilise pas ou ne compte pas vraiment utiliser C99 et je pense que beaucoup pensent de la même façon.
BobbyShaftoe
6
@BobbyShaftoe: L'affiche originale a explicitement déclaré dans un commentaire que C90 en était un exemple.
Keith Thompson
32

C99 l'a dans stdbool.h , mais dans C90 il doit être défini comme typedef ou enum:

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

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

Alternativement:

typedef enum { FALSE, TRUE } boolean;

boolean b = FALSE;
if (b) { ... }
Rob
la source
5
Notez que le comportement du typedef sera différent de celui du C99 bool, et également différent de celui de nombreux bittypes de compilateurs . Par exemple, bool x=4294967296LL;ou bool x=0.1;définirait xun sur C99, mais mettrait probablement la plupart des versions typedef à zéro.
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. */
user2705144
la source
16
Les valeurs initiales sont totalement inutiles. typedef enum { false, true };est tout aussi bon. Si vous insistez pour être plus explicite, vous pouvez écrire typedef enum { false = 0, true = 1 };. (Ou tout simplement #include <stdbool.h>si votre compilateur le prend en charge; il est standard depuis 14 ans.)
Keith Thompson
9
@KeithThompson Les valeurs initiales peuvent être inutiles, mais cette réponse les choisit de manière très élégante, non pas avec des valeurs arbitraires, mais en utilisant la propre sémantique des langues et en laissant le compilateur décider.
MestreLion
11
@MestreLion: La propre sémantique du langage garantit que cela typedef enum { false, true } bool;fonctionne exactement comme prévu. 1 == 0et ! falsene sont pas élégants, ils sont simplement obscurcis. Il n'y a aucune décision à prendre par le compilateur; il doit obéir à la sémantique définie par le langage.
Keith Thompson
11
@KeithThompson: Je ne pense pas qu'ils soient obscurcis, je suppose que l'intention de l'auteur était de choisir les valeurs les plus "naturelles": falseest réglé sur la valeur que le langage dit qu'une inégalité devrait être évaluée et truesur son "opposé" ( encore une fois, quoi que ce soit). De cette façon, il ne faut pas se soucier si c'est {1, 0}, {-1, 0}, {0, 1}, etc., et il est garanti de fonctionner dans les comparaisons, car il a été conçu en utilisant un.
MestreLion
3
@MestreLion: Quiconque connaît C connaît les valeurs numériques de falseet true. Quiconque ne connaît pas C n'est pas le public attendu pour le code C. Et comme je l'ai dit, C a un type booléen intégré depuis le millénaire précédent.
Keith Thompson
12

_Boolest un mot-clé en C99: il spécifie un type, tout comme intou double.

6.5.2

2 Un objet déclaré comme type _Bool est suffisamment grand pour stocker les valeurs 0 et 1.

pmg
la source
6

C99 définit bool trueet falsein stdbool.h.

starblue
la source
2

stdbool.h a été introduit en c99

Nick Van Brunt
la source
1

stdbool.h définit les macros vrai et faux, mais rappelez-vous qu'il a été défini comme étant 1 et 0.

C'est pourquoi sizeof(true)est 4.

Neha Gangwar
la source
0

Pas une telle chose, probablement juste une macro pour int

sindre j
la source
Nice with -1's ... la question était C90, pas 99 je crois
sindre j
5
Eh bien, il dit standard C par exemple C90, je suppose que cela comprend C99.
Matt Joiner
2
Il mentionne spécifiquement C90, PAS C99, donc je suppose que ce qu'il veut dire. Selon wikipedia, le seul compilateur qui prend entièrement en charge C99 est Sun Studio de Sun Microsystems. Maintenant, ce n'est guère une norme largement acceptée, n'est-ce pas? On peut dire que la plupart des compilateurs modernes implémentent des parties de la norme C99, j'aurais probablement dû mentionner cela pour éviter des commentaires stupides comme le vôtre! Qu'est-ce que java ou c # à faire avec ce btw?
sindre j
8
l'extension C standard (par exemple, ISO C90) classe le type de normes C qui l'intéresse, pas spécifiquement C90 lui-même. une réponse appropriée à cette question est, oui une norme C tels que C90, en particulier la norme C99, ne mette en œuvre un boolgenre.
Matt Joiner
0

C99 a ajouté un booltype dont la sémantique est fondamentalement différente de celles de presque tous les types entiers qui existaient auparavant en C, y compris les types définis par l'utilisateur et d'extension de compilateur destinés à de telles fins, et que certains programmes peuvent avoir "type-def" ed à bool.

Par exemple, étant donné que bool a = 0.1, b=2, c=255, d=256;le booltype C99 définirait les quatre objets sur 1. Si un programme C89 était utilisé typedef unsigned char bool, les objets recevraient respectivement 0, 1, 255 et 0. S'il est utilisé char, les valeurs peuvent être les mêmes que ci-dessus ou c-1. S'il avait utilisé une extension bitou un __bittype de compilateur , les résultats seraient probablement 0, 0, 1, 0 (en traitant bitd'une manière équivalente à un champ de bits non signé de taille 1 ou à un type entier non signé avec un bit de valeur).

supercat
la source