Apakah bool adalah tipe C asli?

265

Saya perhatikan bahwa kode kernel Linux menggunakan bool, tapi saya pikir bool adalah tipe C ++. Apakah bool ekstensi C standar (misalnya, ISO C90) atau ekstensi GCC?

asussex
sumber
2
Bagian 9 dari FAQ comp.lang.c membahas hal ini.
Keith Thompson
1
Tautan langsung: c-faq.com/bool/index.html
Ellen Spertus
Kernel Linux menggunakan -std=gnu89yang mendukung _Boolsebagai ekstensi ke C90. "include / linux / types.h" telah typedef _Bool bool;.
Ian Abbott
Juga, FWIW, kernel Linux 2.6.19 adalah versi pertama yang digunakan typedef _Bool bool;(komit 6e21828743247270d09a86756a0c11702500dbfb ) dan membutuhkan GNU C 3.2 atau lebih baru.
Ian Abbott

Jawaban:

368

bool ada di C - C99 saat ini, tetapi tidak di C89 / 90.

Dalam C99 jenis asli sebenarnya disebut _Bool, sedangkan boolmakro perpustakaan standar didefinisikan dalam stdbool.h(yang diharapkan untuk diselesaikan _Bool). Objek tipe _Boolmemegang 0 atau 1, sementara truedan falsejuga makro dari stdbool.h.

Perhatikan, BTW, bahwa ini menyiratkan bahwa preprosesor C akan menafsirkan #if truesebagai #if 0kecuali stdbool.hdisertakan. Sementara itu, preprocessor C ++ diperlukan untuk secara asli mengenali truesebagai bahasa literal.

Semut
sumber
62
Ada standar ISO C baru, yang diterbitkan pada 2011 (setelah jawaban ini diposting). ANSI, seperti biasa, telah mengadopsi standar ISO C11 sebagai standar ANSI. Untuk alasan historis, frasa "ANSI C" umumnya (tetapi tidak tepat) mengacu pada bahasa yang didefinisikan oleh standar ANSI C89 / ISO C90. Karena standar C sekarang diterbitkan oleh ISO terlebih dahulu, dan karena sudah ada tiga standar ISO C, dengan berbagai tingkat adopsi, yang terbaik adalah merujuk pada tahun standar tersebut dipublikasikan (ISO C90, ISO C99, ISO C11) untuk menghindari kebingungan.
Keith Thompson
8
Apakah ini berarti _Boolmembutuhkan 1 bit memori?
Geremia
27
@Geremia: Tidak. Kenapa? Dalam C setiap objek yang dapat dialamatkan harus menempati setidaknya 1 byte. Dan dalam implementasi kehidupan nyata _Boolbiasanya membutuhkan 1 byte memori. Namun, spesifikasi bahasa secara eksplisit mengizinkan penggunaan _Boolsebagai tipe bidang-bit, yang berarti bahwa dengan menggunakan bidang-bit Anda dapat menekan _Boolnilai menjadi bit tunggal (di dalam struct yang lebih besar).
AnT
@ ANT Bagaimana _Boolnilai bisa langsung dialamatkan (yaitu berukuran 1 byte) dan juga berpartisipasi dalam bidang-bit? Array _Boolmasih akan membutuhkan semua elemennya untuk dialamatkan (misalnya _Bool* ptr = &boolArray[123]).
Dai
118

C99 menambahkan _Booltipe data bawaan (lihat Wikipedia untuk detail), dan jika Anda #include <stdbool.h>, itu menyediakan boolsebagai makro untuk _Bool.

Anda bertanya tentang kernel Linux pada khususnya. Ini mengasumsikan keberadaan _Booldan menyediakan booltypedef sendiri di include / linux / types.h .

Josh Kelley
sumber
26
Mengenai alasannya, ini memungkinkan untuk tidak didefinisikan dan didefinisikan ulang di mana definisi dapat menyebabkan bentrokan dengan kode lama.
Clifford
32

Tidak, tidak ada booldalam ISO C90.

Berikut daftar kata kunci dalam standar C (bukan 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

Inilah artikel yang membahas beberapa perbedaan lain dengan C seperti yang digunakan dalam kernel dan standar: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html

BobbyShaftoe
sumber
6
Untuk tujuan praktis, apakah itu penting selama masih tidak ada dukungan kompiler yang layak? Bahkan gcc tidak memiliki setengah dari fitur C99 sampai saat ini, dan MSVC tidak memiliki sebagian besar dari mereka, dan mungkin tidak akan pernah ...
Pavel Minaev
5
@ Jonathan Leffler, si penanya secara khusus bertanya tentang ISO C90. :) Sebenarnya, biasanya ketika orang merujuk ke ANSI C mereka meaqn C90. Saya tidak menggunakan atau benar-benar berencana untuk menggunakan C99 dan saya pikir banyak yang merasakan hal yang sama.
BobbyShaftoe
6
@ BobbyShaftoe: Poster asli secara eksplisit mengatakan dalam komentar bahwa C90 adalah contoh.
Keith Thompson
32

C99 memilikinya di stdbool.h , tetapi di C90 harus didefinisikan sebagai typedef atau enum:

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

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

Kalau tidak:

typedef enum { FALSE, TRUE } boolean;

boolean b = FALSE;
if (b) { ... }
rampok
sumber
5
Perhatikan bahwa perilaku typedef akan berbeda dari perilaku C99 bool, dan juga berbeda dari bittipe banyak kompiler . Misalnya, bool x=4294967296LL;atau bool x=0.1;akan diatur xke satu di C99, tetapi kemungkinan akan mengatur sebagian besar versi typedef menjadi nol.
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. */
pengguna2705144
sumber
16
Nilai awal sama sekali tidak perlu. typedef enum { false, true };sama baiknya. Jika Anda bersikeras untuk lebih eksplisit, Anda dapat menulis typedef enum { false = 0, true = 1 };. (Atau hanya #include <stdbool.h>jika kompiler Anda mendukungnya; itu sudah standar selama 14 tahun.)
Keith Thompson
9
@KeithThompson Nilai awal mungkin tidak perlu, tetapi jawaban ini memilihnya dengan cara yang sangat elegan, tidak dengan nilai arbitrer, tetapi menggunakan semantik bahasa sendiri dan membiarkan kompilator memutuskan.
MestreLion
11
@MestreLion: Semantik bahasa sendiri menjamin bahwa typedef enum { false, true } bool;berfungsi persis seperti yang diharapkan. 1 == 0dan ! falsetidak elegan, mereka hanya dikaburkan. Tidak ada keputusan untuk dibuat oleh kompiler; itu harus mematuhi semantik yang ditentukan oleh bahasa.
Keith Thompson
11
@KeithThompson: Saya tidak berpikir mereka dikaburkan, saya kira maksud penulis adalah untuk memilih nilai-nilai "alami" yang paling: falsedisetel ke nilai apa pun yang menurut bahasa itu ketidaksetaraan harus dievaluasi, dan trueke "kebalikannya" ( lagi, apa pun itu). Dengan cara ini, seseorang seharusnya tidak peduli apakah itu {1, 0}, {-1, 0}, {0, 1}, dll, dan dijamin akan bekerja dalam perbandingan, karena itu dibuat dengan menggunakan satu.
MestreLion
3
@MestreLion: Siapa pun yang tahu C tahu nilai numerik dari falsedan true. Siapa pun yang tidak tahu C bukan pemirsa yang diharapkan untuk kode C. Dan seperti yang saya katakan, C telah memiliki tipe Boolean bawaan sejak milenium sebelumnya.
Keith Thompson
12

_Booladalah kata kunci dalam C99: itu menentukan jenis, seperti intatau double.

6.5.2

2 Objek yang dideklarasikan sebagai tipe _Bool cukup besar untuk menyimpan nilai 0 dan 1.

pmg
sumber
6

C99 mendefinisikan bool, truedan falsein stdbool.h.

starblue
sumber
2

stdbool.h diperkenalkan pada c99

Nick Van Brunt
sumber
1

stdbool.h mendefinisikan macro benar dan salah, tapi ingat itu didefinisikan sebagai 1 dan 0.

Itu sebabnya sizeof(true)4.

Neha Gangwar
sumber
0

Tidak ada hal seperti itu, mungkin hanya makro untuk int

sindre j
sumber
Baik dengan -1's ... pertanyaannya adalah C90, bukan 99 saya percaya
sindre j
5
baik katanya standar C misalnya C90, saya berasumsi itu termasuk C99.
Matt Joiner
2
Dia menyebutkan C90 secara spesifik, BUKAN C99, jadi saya berasumsi itu yang dia maksud. Menurut wikipedia, satu-satunya kompiler yang sepenuhnya mendukung C99 adalah Sun Studio dari Sun Microsystems. Nah, itu bukan standar yang diterima luas kan? Mungkin kompiler paling modern DO menerapkan bagian dari standar C99, saya mungkin harus menyebutkan bahwa untuk menghindari komentar bodoh seperti milik Anda! Apa hubungannya java atau c # dengan btw ini?
sindre j
8
ekstensi C standar (misalnya, ISO C90) mengklasifikasikan jenis standar C yang ia minati, tidak secara khusus C90 itu sendiri. jawaban yang tepat untuk ini adalah, ya C standar seperti C90, khususnya standar C99, tidak menerapkan booljenis.
Matt Joiner
0

C99 menambahkan booljenis yang semantiknya secara fundamental berbeda dari hampir semua jenis bilangan bulat yang telah ada sebelumnya di C, termasuk jenis yang ditentukan pengguna dan ekstensi-ekstensi yang ditujukan untuk tujuan tersebut, dan yang beberapa program mungkin memiliki "tipe-def" ed untukbool .

Sebagai contoh, diberikan bool a = 0.1, b=2, c=255, d=256;, booltipe C99 akan mengatur keempat objek menjadi 1. Jika program C89 digunakan typedef unsigned char bool, objek akan menerima masing-masing 0, 1, 255, dan 0. Jika digunakan char, nilainya mungkin seperti di atas, atau cmungkin -1. Jika telah menggunakan ekstensi bitatau __bittipe kompiler , hasilnya kemungkinan akan 0, 0, 1, 0 (memperlakukan bitdengan cara yang setara dengan bidang bit yang tidak ditandatangani dari ukuran 1, atau tipe bilangan bulat yang tidak ditandatangani dengan satu bit nilai).

supercat
sumber