Bool é um tipo C nativo?


265

Percebi que o código do kernel Linux usa bool, mas achei que o bool era do tipo C ++. Bool é uma extensão C padrão (por exemplo, ISO C90) ou uma extensão GCC?


2
A seção 9 das perguntas frequentes do comp.lang.c discute isso.
21113 Keith Thompson


O kernel Linux usa o -std=gnu89qual suporta _Boolcomo uma extensão ao C90. "inclui / linux / types.h" possui typedef _Bool bool;.
Ian Abbott

Além disso, FWIW, o kernel do Linux 2.6.19 foi a primeira versão a ser usada typedef _Bool bool;(commit 6e21828743247270d09a86756a0c11702500dbfb ) e exigiu o GNU C 3.2 ou posterior.
Ian Abbott

Respostas:


368

bool existe no C - C99 atual, mas não no C89 / 90.

Em C99, o tipo nativo é realmente chamado _Bool, enquanto boolé uma macro de biblioteca padrão definida em stdbool.h(que é esperado que seja resolvida _Bool). Objetos do tipo _Boolmantêm 0 ou 1, while truee falsetambém são macros stdbool.h.

Observe, BTW, que isso implica que o pré-processador C interpretará #if truecomo a #if 0menos que stdbool.hesteja incluído. Enquanto isso, o pré-processador C ++ é necessário para reconhecer nativamente truecomo um literal de linguagem.


62
Existe um novo padrão ISO C, publicado em 2011 (após a publicação desta resposta). A ANSI, como sempre, adotou o padrão ISO C11 como um padrão ANSI. Por razões históricas, a frase "ANSI C" geralmente (mas incorretamente) refere-se ao idioma definido pelo padrão ANSI C89 / ISO C90. Como os padrões C agora são publicados pela ISO pela primeira vez e como existem três padrões ISO C, com diferentes níveis de adoção, é melhor se referir ao ano em que o padrão foi publicado (ISO C90, ISO C99, ISO C11) para evitar confusão.
21413 Keith Thompson

8
Isso significa que _Boolocupa 1 bit de memória?
Geremia

27
@ Geremia: Não. Por que? Em C, cada objeto endereçável deve ocupar pelo menos 1 byte. E na vida real, as implementações _Boolgeralmente levam 1 byte de memória. No entanto, a especificação de linguagem permite explicitamente o uso _Boolcomo tipo de campo de bits, o que significa que, usando campos de bits, você pode compactar um _Boolvalor em um único bit (dentro de uma estrutura maior).
AnT

@AnT Como um _Boolvalor pode ser endereçável diretamente (ou seja, tamanho de 1 byte) e também participar de um campo de bits? Uma matriz _Boolainda exigiria que todos os seus elementos fossem endereçáveis ​​(por exemplo _Bool* ptr = &boolArray[123]).
Dai

118

O C99 adicionou um _Booltipo de dados interno (consulte a Wikipedia para obter detalhes) e, se você #include <stdbool.h>, ele fornece boolcomo uma macro para _Bool.

Você perguntou sobre o kernel do Linux em particular. Ele assume a presença _Boole fornece o boolpróprio typedef em include / linux / types.h .


26
Quanto ao motivo, é para permitir que ele não seja indefinido e redefinido, onde sua definição possa causar um conflito com o código legado.
Clifford

32

Não, não existe boolna ISO C90.

Aqui está uma lista de palavras-chave no padrão C (não no 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

Aqui está um artigo discutindo algumas outras diferenças com o C usadas no kernel e no padrão: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html


6
Para fins práticos, isso realmente importa desde que ainda não haja suporte decente ao compilador? Até o gcc não possuía metade dos recursos do C99 até recentemente, e o MSVC não possui a maioria deles, e provavelmente nunca terá ...
Pavel Minaev

5
@ Jonathan Leffler, o questionador perguntou especificamente sobre a ISO C90. :) De fato, geralmente quando as pessoas se referem ao ANSI C, elas significam C90. Eu não uso ou realmente pretendo usar o C99 e acho que muitos se sentem da mesma maneira.
BobbyShaftoe

6
@BobbyShaftoe: O pôster original disse explicitamente em um comentário que o C90 era um exemplo.
Keith Thompson

32

O C99 possui no stdbool.h , mas no C90 deve ser definido como um typedef ou enum:

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

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

Alternativamente:

typedef enum { FALSE, TRUE } boolean;

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

5
Observe que o comportamento do typedef será diferente daquele do C99 boole também do comportamento de muitos bittipos de compiladores . Por exemplo, bool x=4294967296LL;ou bool x=0.1;definiria xcomo um no C99, mas provavelmente definiria a maioria das versões de typedef para 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
Os valores iniciais são totalmente desnecessários. typedef enum { false, true };é tão bom. Se você insistir em ser mais explícito, pode escrever typedef enum { false = 0, true = 1 };. (Ou apenas #include <stdbool.h>se o seu compilador suporta, tem sido padrão para 14 anos.)
Keith Thompson

9
@KeithThompson Os valores iniciais podem ser desnecessários, mas esta resposta os escolhe de uma maneira muito elegante, não com valores arbitrários, mas usando a própria semântica dos idiomas e deixando o compilador decidir.
MestreLion 16/02

11
@MestreLion: A própria semântica da linguagem garante que typedef enum { false, true } bool;funciona exatamente como o esperado. 1 == 0e ! falsenão são elegantes, são apenas ofuscados. Não há decisão para o compilador tomar; deve obedecer à semântica definida pelo idioma.
21415 Keith Thompson

11
@KeithThompson: Eu não acho que eles sejam ofuscados, acho que a intenção do autor era escolher os valores mais "naturais": falseé definido como qualquer valor para o qual a linguagem diz que uma desigualdade deve ser avaliada e trueseu "oposto" ( novamente, seja o que for). Dessa forma, não se deve importar se são {1, 0}, {-1, 0}, {0, 1} etc., e é garantido que funcione em comparações, porque foi criada usando uma.
MestreLion 16/02

3
@MestreLion: Quem conhece C sabe os valores numéricos de falsee true. Quem não conhece C não é o público esperado para o código C. E, como eu disse, C possui um tipo booleano incorporado desde o milênio anterior.
Keith Thompson

12

_Boolé uma palavra-chave em C99: especifica um tipo, assim como intou double.

6.5.2

2 Um objeto declarado como tipo _Bool é grande o suficiente para armazenar os valores 0 e 1.




1

stdbool.h define macros true e false, mas lembre-se de que elas são definidas como 1 e 0.

É por isso que sizeof(true)é 4.


0

Não existe, provavelmente apenas uma macro para int


Agradável com -1 de ... a pergunta era C90, não 99 eu acredito
j Sindre

5
bem, ele diz C padrão, por exemplo , C90, presumo que inclui C99.
Matt Joiner

2
Ele menciona C90 espesificamente, NÃO C99, então suponho que ele queira dizer. De acordo com a wikipedia, o único compilador que suporta totalmente o C99 é o Sun Studio, da Sun Microsystems. Agora, esse dificilmente é um padrão amplamente aceito, não é? Indiscutivelmente a maioria dos compiladores modernos implementa partes do padrão C99, eu provavelmente deveria ter mencionado isso para evitar comentários estúpidos como o seu! O que é java ou c # a ver com este btw?
Sindre j

8
A extensão C padrão (por exemplo, ISO C90) está classificando o tipo de padrão C em que ele está interessado, não especificamente o próprio C90. uma resposta adequada a este é, sim um C padrão, tais como C90, especificamente o padrão C99, se implementar um booltipo.
Matt Joiner

0

O C99 adicionou um booltipo cuja semântica é fundamentalmente diferente daquela de quase todos os tipos inteiros que existiam antes em C, incluindo tipos definidos pelo usuário e de extensão do compilador destinados a esses fins, e que alguns programas podem ter "tipos def" parabool .

Por exemplo, dado bool a = 0.1, b=2, c=255, d=256;, o booltipo C99 definiria todos os quatro objetos como 1. Se um programa C89 typedef unsigned char boolfosse usado , os objetos receberiam 0, 1, 255 e 0, respectivamente. Se usado char, os valores podem ser os acima, ou cpode ser -1. Se ele tivesse usado uma extensão bitou __bittipo de compilador , os resultados provavelmente seriam 0, 0, 1, 0 (tratando de bitmaneira equivalente a um campo de bits não assinado do tamanho 1 ou um tipo inteiro não assinado com um bit de valor).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.