Ist bool ein nativer C-Typ?

265

Ich habe festgestellt, dass der Linux-Kernel-Code Bool verwendet, aber ich dachte, dass Bool ein C ++ - Typ ist. Ist bool eine Standard-C-Erweiterung (z. B. ISO C90) oder eine GCC-Erweiterung?

Asussex
quelle
2
In Abschnitt 9 der FAQ zu comp.lang.c wird dies erläutert.
Keith Thompson
1
Direkter Link: c-faq.com/bool/index.html
Ellen Spertus
Die Linux - Kernel verwendet -std=gnu89die Stützen _Boolals Erweiterung C90. "include / linux / types.h" hat typedef _Bool bool;.
Ian Abbott
Außerdem war FWIW, der Linux-Kernel 2.6.19, die erste verwendete Version typedef _Bool bool;(Commit 6e21828743247270d09a86756a0c11702500dbfb ) und erforderte GNU C 3.2 oder höher.
Ian Abbott

Antworten:

368

bool existiert im aktuellen C - C99, aber nicht in C89 / 90.

In C99 wird der native Typ tatsächlich aufgerufen _Bool, während boolein Standardbibliotheksmakro definiert ist stdbool.h(das voraussichtlich in aufgelöst wird _Bool). Objekte vom Typ enthalten _Boolentweder 0 oder 1, während trueund falsesind auch Makros von stdbool.h.

Übrigens, dies impliziert, dass der C-Präprozessor so interpretiert wird, #if trueals wäre er #if 0nicht stdbool.henthalten. In der Zwischenzeit muss der C ++ - Präprozessor nativ trueals Sprachliteral erkannt werden .

Ameise
quelle
62
Es gibt einen neuen ISO C-Standard, der 2011 veröffentlicht wurde (nachdem diese Antwort veröffentlicht wurde). ANSI hat wie üblich den ISO C11-Standard als ANSI-Standard übernommen. Aus historischen Gründen bezieht sich der Ausdruck "ANSI C" allgemein (aber unkorrekt) auf die Sprache, die durch den ANSI C89 / ISO C90-Standard definiert ist. Da C-Standards jetzt zuerst von ISO veröffentlicht werden und es drei ISO C-Standards mit unterschiedlichem Akzeptanzgrad gibt, ist es am besten, sich auf das Jahr zu beziehen, in dem der Standard veröffentlicht wurde (ISO C90, ISO C99, ISO C11), um dies zu vermeiden Verwirrtheit.
Keith Thompson
8
Bedeutet dies, dass _Bool1 Bit Speicherplatz benötigt wird?
Geremia
27
@Geremia: Nein. Warum? In C muss jedes adressierbare Objekt mindestens 1 Byte belegen. In der Praxis benötigen Implementierungen _Boolnormalerweise 1 Byte Speicher. Die Sprachspezifikation erlaubt jedoch ausdrücklich die Verwendung _Boolals Bitfeldtyp, was bedeutet, dass Sie durch die Verwendung von Bitfeldern einen _BoolWert in ein einzelnes Bit (innerhalb einer größeren Struktur) drücken können .
Am
@AnT Wie kann ein _BoolWert sowohl direkt adressierbar sein (dh 1 Byte groß sein) als auch an einem Bitfeld teilnehmen? Ein Array von _Boolwürde immer noch erfordern, dass alle seine Elemente adressierbar sind (z _Bool* ptr = &boolArray[123]. B. ).
Dai
118

C99 hat einen eingebauten _BoolDatentyp hinzugefügt (siehe Wikipedia für Details), und wenn Sie #include <stdbool.h>dies tun , wird er boolals Makro bereitgestellt _Bool.

Sie haben insbesondere nach dem Linux-Kernel gefragt. Es setzt das Vorhandensein von _Boolund stellt selbst ein booltypedef in include / linux / types.h bereit .

Josh Kelley
quelle
26
Es ist zuzulassen, dass es nicht undefiniert und neu definiert wird, wenn seine Definition zu einem Konflikt mit dem Legacy-Code führen kann.
Clifford
32

Nein, es gibt keine boolin ISO C90.

Hier ist eine Liste der Schlüsselwörter in Standard C (nicht 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

In diesem Artikel werden einige andere Unterschiede zu C erläutert, wie sie im Kernel und im Standard verwendet werden: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html

BobbyShaftoe
quelle
6
Ist es aus praktischen Gründen wirklich wichtig, solange es noch keine anständige Compiler-Unterstützung gibt? Sogar gcc hatte bis vor kurzem nicht die Hälfte der C99-Funktionen, und MSVC hat die meisten davon nicht und wird es wahrscheinlich nie ...
Pavel Minaev
5
@ Jonathan Leffler, der Fragesteller fragte speziell nach ISO C90. :) In der Tat, normalerweise, wenn Leute sich auf ANSI C beziehen, messen sie C90. Ich benutze C99 nicht oder plane es wirklich und ich denke, viele denken genauso.
BobbyShaftoe
6
@ BobbyShaftoe: Das Originalplakat sagte in einem Kommentar ausdrücklich, dass C90 ein Beispiel sei.
Keith Thompson
32

C99 hat es in stdbool.h , aber in C90 muss es als typedef oder enum definiert sein:

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

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

Alternative:

typedef enum { FALSE, TRUE } boolean;

boolean b = FALSE;
if (b) { ... }
rauben
quelle
5
Beachten Sie, dass sich das Verhalten des typedef von dem des C99 boolund auch von dem vieler Compilertypen bitunterscheidet. Zum Beispiel bool x=4294967296LL;oder bool x=0.1;würde xauf C99 auf eins gesetzt, würde aber wahrscheinlich die meisten typedef-Versionen auf null setzen.
Superkatze
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
quelle
16
Die Anfangswerte sind völlig unnötig. typedef enum { false, true };ist genauso gut. Wenn Sie darauf bestehen, expliziter zu sein, können Sie schreiben typedef enum { false = 0, true = 1 };. (Oder nur, #include <stdbool.h>wenn Ihr Compiler es unterstützt; es ist seit 14 Jahren Standard.)
Keith Thompson
9
@KeithThompson Anfangswerte sind möglicherweise nicht erforderlich, aber diese Antwort wählt sie auf sehr elegante Weise aus, nicht mit beliebigen Werten, sondern unter Verwendung der eigenen Semantik der Sprache und unter Entscheidung des Compilers.
MestreLion
11
@MestreLion: Die spracheigene Semantik garantiert, dass typedef enum { false, true } bool;genau wie erwartet funktioniert. 1 == 0und ! falsesind nicht elegant, sie sind nur verschleiert. Der Compiler muss keine Entscheidung treffen. es muss der durch die Sprache definierten Semantik gehorchen.
Keith Thompson
11
@KeithThompson: Ich glaube nicht, dass sie verschleiert sind. Ich denke, die Absicht des Autors war es, die "natürlichsten" Werte zu wählen: Wird falseauf den Wert gesetzt, zu dem die Sprache sagt, dass eine Ungleichung bewertet werden sollte, und trueauf das "Gegenteil" ( wieder was auch immer das ist). Dieser Weg soll es egal , ob das heißt {1, 0}, {-1, 0}, {0, 1}, etc, und es wird in Vergleich zu der Arbeit garantiert, denn es wurde in Handarbeit eines verwenden.
MestreLion
3
@MestreLion: Jeder, der C kennt, kennt die numerischen Werte von falseund true. Wer C nicht kennt, ist nicht die erwartete Zielgruppe für C-Code. Und wie gesagt, C hat seit dem letzten Jahrtausend einen eingebauten Booleschen Typ.
Keith Thompson
12

_Boolist ein Schlüsselwort in C99: Es gibt einen Typ an, genau wie intoder double.

6.5.2

2 Ein als Typ _Bool deklariertes Objekt ist groß genug, um die Werte 0 und 1 zu speichern.

pmg
quelle
6

C99 definiert bool trueund falsein stdbool.h.

Sternenblau
quelle
2

stdbool.h wurde in c99 eingeführt

Nick Van Brunt
quelle
1

stdbool.h definiert Makros als wahr und falsch, aber denken Sie daran, dass sie als 1 und 0 definiert sind.

Deshalb sizeof(true)ist 4.

Neha Gangwar
quelle
0

Kein solches Ding, wahrscheinlich nur ein Makro für int

sindre j
quelle
Schön mit -1 ... die Frage war C90, nicht 99, glaube ich
sindre j
5
Nun, er sagt C-Standard, zB C90, ich nehme an, das beinhaltet C99.
Matt Joiner
2
Er erwähnt C90 speziell, NICHT C99, also nehme ich an, was er meint. Laut Wikipedia ist Sun Studio von Sun Microsystems der einzige Compiler, der C99 vollständig unterstützt. Nun, das ist kaum ein allgemein anerkannter Standard, oder? Wahrscheinlich implementieren die meisten modernen Compiler Teile des C99-Standards. Ich hätte das wahrscheinlich erwähnen sollen, um dumme Kommentare wie Ihre zu vermeiden! Was hat Java oder C # damit zu tun?
Sindre J
8
Die Standard-C-Erweiterung (z. B. ISO C90) klassifiziert die Art von C-Standards, an denen er interessiert ist, nicht speziell C90 selbst. eine angemessene Antwort auf diese Frage ist, ja ein C wie C90 - Standard, insbesondere der C99 - Standard, ist eine Umsetzung boolArt.
Matt Joiner
0

C99 fügte einen boolTyp hinzu, dessen Semantik sich grundlegend von der nahezu aller Ganzzahltypen unterscheidet, die zuvor in C vorhanden waren, einschließlich benutzerdefinierter und Compiler-Erweiterungstypen, die für solche Zwecke vorgesehen sind und die einige Programme möglicherweise "typdefiniert" haben zu bool.

Beispielsweise würde bool a = 0.1, b=2, c=255, d=256;der boolTyp C99 alle vier Objekte auf 1 setzen. Wenn ein C89-Programm verwendet würde typedef unsigned char bool, würden die Objekte 0, 1, 255 bzw. 0 empfangen. Wenn es verwendet wird char, können die Werte wie oben oder c-1 sein. Wenn eine Compiler-Erweiterung bitoder ein Compiler- __bitTyp verwendet worden wäre, wären die Ergebnisse wahrscheinlich 0, 0, 1, 0 (Behandlung bitin einer Weise, die einem vorzeichenlosen Bitfeld der Größe 1 oder einem vorzeichenlosen Integer-Typ mit einem Wertbit entspricht).

Superkatze
quelle