บูลเป็นชนิด C ดั้งเดิมหรือไม่


265

ฉันสังเกตว่ารหัสเคอร์เนลของ Linux ใช้บูล แต่ฉันคิดว่าบูลนั้นเป็นประเภท C ++ บูลเป็นส่วนขยาย C มาตรฐาน (เช่น ISO C90) หรือส่วนขยาย GCC หรือไม่


2
ส่วนที่ 9 ของcomp.lang.c คำถามที่พบบ่อยกล่าวถึงเรื่องนี้
Keith Thompson

1
ลิงก์โดยตรง: c-faq.com/bool/index.html
Ellen Spertus

เคอร์เนล Linux ใช้-std=gnu89ซึ่งรองรับ_Boolเป็นส่วนขยายของ C90 "รวม / Linux / types.h" typedef _Bool bool;มี
Ian Abbott

นอกจากนี้ FWIW, เคอร์เนล Linux 2.6.19 เป็นรุ่นแรกที่ใช้typedef _Bool bool;(กระทำ6e21828743247270d09a86756a0c11702500dbfb ) และต้องใช้ GNU C 3.2 หรือใหม่กว่า
Ian Abbott

คำตอบ:


368

bool มีอยู่ในปัจจุบัน C - C99 แต่ไม่ใช่ใน C89 / 90

ใน C99 ชนิดเนทีฟนั้นถูกเรียกใช้จริง_Boolในขณะที่boolเป็นแมโครไลบรารีมาตรฐานที่กำหนดไว้stdbool.h(ซึ่งคาดว่าจะแก้ไขได้_Bool) วัตถุประเภท_Boolถือ 0 หรือ 1 ในขณะที่trueและนอกจากนี้ยังมีแมโครจากfalsestdbool.h

หมายเหตุ BTW ว่านี่หมายความว่า C preprocessor จะตีความ#if trueว่าเป็น#if 0ถ้าstdbool.hรวมอยู่ ในขณะเดียวกันตัวประมวลผลล่วงหน้า C ++ จำเป็นต้องรับรู้trueอย่างแท้จริงว่าเป็นตัวอักษรภาษา


62
มีมาตรฐาน ISO C ใหม่เผยแพร่ในปี 2011 (หลังจากโพสต์คำตอบนี้แล้ว) ANSI ตามปกติได้นำมาตรฐาน ISO C11 มาใช้เป็นมาตรฐาน ANSI ด้วยเหตุผลทางประวัติศาสตร์วลี "ANSI C" โดยทั่วไป (แต่ไม่ครอบคลุม) หมายถึงภาษาที่กำหนดโดยมาตรฐาน ANSI C89 / ISO C90 เนื่องจากมาตรฐาน C ได้รับการเผยแพร่โดย ISO เป็นครั้งแรกและเนื่องจากมีสามมาตรฐาน ISO C ที่มีระดับการยอมรับที่แตกต่างกันดังนั้นจึงควรอ้างอิงถึงปีที่มีการเผยแพร่ publshed (ISO C90, ISO C99, ISO C11) ความสับสน
Keith Thompson

8
หมายความว่า_Boolต้องใช้หน่วยความจำ 1 บิตหรือไม่
Geremia

27
@ Geremia: ไม่ทำไม ใน C แต่ละวัตถุที่แอดเดรสได้จะต้องมีอย่างน้อย 1 ไบต์ และในการใช้งานจริง_Boolมักใช้หน่วยความจำ 1 ไบต์ อย่างไรก็ตามข้อกำหนดทางภาษาอนุญาตให้ใช้_Boolเป็นประเภทบิตฟิลด์อย่างชัดเจนซึ่งหมายความว่าโดยการใช้บิตฟิลด์คุณสามารถบีบ_Boolค่าเป็นบิตเดียว (ภายในโครงสร้างที่มีขนาดใหญ่กว่า)
AnT

@AnT _Boolค่าสามารถกำหนดแอดเดรสได้โดยตรง (เช่นขนาด 1 ไบต์) และมีส่วนร่วมในบิตฟิลด์ได้อย่างไร อาร์เรย์ของ_Boolจะยังคงต้องการองค์ประกอบทั้งหมดของมันจะอยู่ (เช่น_Bool* ptr = &boolArray[123])
ได

118

C99 เพิ่มในตัว_Boolชนิดข้อมูล (ดูวิกิพีเดียสำหรับรายละเอียด) และถ้าคุณ#include <stdbool.h>จะให้เป็นแมโครไปbool_Bool

คุณถามเกี่ยวกับเคอร์เนล Linux โดยเฉพาะ จะถือว่าการปรากฏตัวของ_Boolและให้booltypedef ตัวเองในการรวม / Linux / types.h


26
สำหรับสาเหตุที่ทำให้ไม่สามารถกำหนดและนิยามใหม่ได้ซึ่งคำจำกัดความอาจทำให้เกิดการปะทะกับรหัสดั้งเดิม
Clifford

32

ไม่ไม่มีboolใน ISO C90

นี่คือรายการคำหลักในมาตรฐาน C (ไม่ใช่ 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

นี่คือบทความที่พูดถึงความแตกต่างอื่น ๆกับ C ที่ใช้ในเคอร์เนลและมาตรฐาน: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html


6
สำหรับการใช้งานจริงมันมีความสำคัญตราบใดที่ยังไม่มีคอมไพเลอร์ที่เหมาะสม? แม้ GCC ไม่ได้ครึ่งหนึ่งของ C99 มีจนกระทั่งเมื่อเร็ว ๆ และ MSVC ไม่ได้มากที่สุดของพวกเขาและอาจจะไม่ ...
พาเวล Minaev

5
@Jathanathan Leffler ผู้ถามได้ถามเฉพาะเกี่ยวกับ ISO C90 :) โดยปกติแล้วเมื่อผู้คนพูดถึง ANSI C พวกเขา meaqn C90 ฉันไม่ได้ใช้หรือวางแผนที่จะใช้ C99 และฉันคิดว่าหลายคนรู้สึกแบบเดียวกัน
BobbyShaftoe

6
@BobbyShaftoe: โปสเตอร์ต้นฉบับกล่าวอย่างชัดเจนในความคิดเห็นว่า C90 เป็นตัวอย่าง
Keith Thompson

32

C99 มีstdbool.hแต่ใน C90 ต้องกำหนดเป็น typedef หรือ enum:

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

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

อีกวิธีหนึ่งคือ:

typedef enum { FALSE, TRUE } boolean;

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

5
โปรดทราบว่าพฤติกรรมของ typedef จะแตกต่างจาก C99 boolและแตกต่างจากคอมไพเลอร์หลายbitประเภท ตัวอย่างเช่นbool x=4294967296LL;หรือbool x=0.1;ตั้งxเป็นหนึ่งใน C99 แต่น่าจะตั้งรุ่น typedef ส่วนใหญ่เป็นศูนย์
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
ค่าเริ่มต้นนั้นไม่จำเป็นเลย typedef enum { false, true };เป็นสิ่งที่ดี typedef enum { false = 0, true = 1 };หากคุณยืนยันในการเป็นที่ชัดเจนมากขึ้นคุณสามารถเขียน (หรือ#include <stdbool.h>ถ้าคอมไพเลอร์ของคุณรองรับมันเป็นมาตรฐานมา 14 ปีแล้ว)
Keith Thompson

9
@KeithThompson ค่าเริ่มต้นอาจไม่จำเป็น แต่คำตอบนี้เลือกอย่างหรูหราไม่ใช่ด้วยค่าที่กำหนดเอง แต่ใช้ความหมายของภาษาและให้คอมไพเลอร์เป็นผู้ตัดสินใจ
MestreLion

11
@MestreLion: การรับประกันความหมายของภาษานั้นtypedef enum { false, true } bool;ทำงานได้อย่างตรงตามที่คาดไว้ 1 == 0และ! falseไม่สง่างามพวกเขาเพียง แต่งงงวย ไม่มีการตัดสินใจให้เรียบเรียง มันจะต้องเชื่อฟังความหมายที่กำหนดโดยภาษา
Keith Thompson

11
@ KeithThompson: ฉันไม่คิดว่าพวกเขาจะงงงวยฉันคิดว่าความตั้งใจของผู้เขียนคือการเลือกค่านิยม "ธรรมชาติ" ที่สุด: falseตั้งค่าเป็นสิ่งที่ภาษาพูดว่าควรจะประเมินความไม่เท่าเทียมกันและtrue"ตรงกันข้าม" ( อีกครั้งอะไรก็ตามที่เป็น) วิธีนี้ไม่ควรสนใจถ้านั่นคือ {1, 0}, {-1, 0}, {0, 1}, และอื่น ๆ และรับประกันว่าจะทำงานในการเปรียบเทียบเพราะมันถูกสร้างขึ้นมา โดยใช้วิธีการอย่างใดอย่างหนึ่ง
MestreLion

3
@MestreLion: ทุกคนที่รู้ C รู้ค่าเป็นตัวเลขของและfalse trueทุกคนที่ไม่รู้จัก C ไม่ใช่ผู้ชมที่คาดหวังสำหรับรหัส C และอย่างที่ฉันได้กล่าวไว้ C มีประเภทบูลีนในตัวตั้งแต่สหัสวรรษที่แล้ว
Keith Thompson

12

_Boolเป็นคำสำคัญใน C99: มันระบุประเภทเช่นเดียวหรือintdouble

6.5.2

2 วัตถุที่ประกาศเป็นประเภท _Bool มีขนาดใหญ่พอที่จะเก็บค่า 0 และ 1




1

stdbool.h กำหนดมาโครจริงและเท็จ แต่จำไว้ว่ามันเป็น 1 และ 0

นั่นคือเหตุผลที่sizeof(true)4


0

ไม่มีสิ่งนั้นอาจเป็นเพียงแมโครสำหรับ int


ดีกับ -1 ของ ... คำถามคือ C90 ไม่ 99 ผมเชื่อว่า
เจ Sindre

5
เขาบอกว่ามาตรฐาน C เช่น C90 ฉันคิดว่ารวม C99
Matt Joiner

2
เขาพูดถึง C90 อย่างเด็ดขาดไม่ใช่ C99 ดังนั้นฉันคิดว่าเขาหมายถึงอะไร คอมไพเลอร์เพียงตัวเดียวที่รองรับ C99 อย่างเต็มที่คือ Sun Studio จาก Sun Microsystems ตอนนี้มันแทบจะไม่เป็นมาตรฐานที่ยอมรับกันแล้วใช่ไหม? เนื้อหาที่ทันสมัยที่สุดคอมไพเลอร์ใช้ส่วนต่าง ๆ ของมาตรฐาน C99 ฉันน่าจะพูดถึงเพื่อหลีกเลี่ยงความคิดเห็นที่โง่เขลาเช่นคุณ! Java หรือ c # เกี่ยวข้องกับ btw นี้อย่างไร
sindre j

8
ส่วนขยาย C มาตรฐาน (เช่น ISO C90)เป็นการจำแนกประเภทของมาตรฐาน C ที่เขาสนใจไม่ใช่เฉพาะ C90 คำตอบที่เหมาะสมสำหรับสิ่งนี้คือใช่มาตรฐาน C เช่น C90 โดยเฉพาะมาตรฐาน C99 จะใช้boolประเภทนี้
Matt Joiner

0

C99 เพิ่มboolประเภทที่มีความหมายพื้นฐานแตกต่างจากประเภทจำนวนเต็มทั้งหมดที่มีอยู่ก่อนใน C รวมถึงผู้ใช้กำหนดและประเภทคอมไพเลอร์ส่วนขยายที่มีไว้สำหรับวัตถุประสงค์ดังกล่าวและโปรแกรมบางโปรแกรมอาจมี "type-def" ed boolไปยัง

ตัวอย่างเช่นที่กำหนดประเภทbool a = 0.1, b=2, c=255, d=256;C99 boolจะตั้งค่าวัตถุทั้งสี่เป็น 1 หากใช้โปรแกรม C89 typedef unsigned char boolวัตถุจะได้รับ 0, 1, 255 และ 0 ตามลำดับ หากใช้charค่าอาจเป็นข้างต้นหรือcอาจเป็น -1 ถ้ามันใช้คอมไพเลอร์ - นามสกุลbitหรือ__bitชนิดผลลัพธ์น่าจะเป็น 0, 0, 1, 0 (ปฏิบัติbitในลักษณะเทียบเท่ากับบิตฟิลด์ที่ไม่ได้ลงนามขนาด 1 หรือประเภทจำนวนเต็มที่ไม่ได้ลงนามด้วยค่าบิตหนึ่ง)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.