Em relação ao tipo booleano em C
Um tipo booleano foi introduzido bastante tarde na linguagem C, no ano de 1999. Antes disso, C não tinha um tipo booleano, mas era usado int
para todas as expressões booleanas. Portanto, todos os operadores lógicos, como > == !
etc, retornam um int
valor 1
ou 0
.
Era costume que os aplicativos usassem tipos caseiros como typedef enum { FALSE, TRUE } BOOL;
, que também se resume a int
tipos de tamanho.
O C ++ tinha um tipo booleano muito melhor e explícito bool
, que não era maior que 1 byte. Enquanto os tipos ou expressões booleanos em C terminariam em 4 bytes no pior caso. Alguma maneira de compatibilidade com C ++ foi introduzida em C com o padrão C99. C então obteve um tipo booleano _Bool
e também o cabeçalho stdbool.h
.
stdbool.h
fornece alguma compatibilidade com C ++. Esse cabeçalho define a macro bool
(a mesma ortografia que a palavra-chave C ++) que se expande para _Bool
, um tipo que é um tipo inteiro pequeno, provavelmente com 1 byte de largura. Da mesma forma, o cabeçalho fornece dois macros true
e false
, mesmo ortografia como palavras-chave C ++, mas com compatibilidade com versões anteriores para programas em C mais velhos . Por isso true
e false
expandir-se para 1
e 0
em C e seu tipo é int
. Essas macros não são realmente do tipo booleano, como seriam as palavras-chave C ++ correspondentes.
Da mesma forma, para fins de compatibilidade com versões anteriores, os operadores lógicos em C ainda retornam um int
até hoje, mesmo que C atualmente tenha um tipo booleano. Enquanto em C ++, operadores lógicos retornam a bool
. Assim, uma expressão como sizeof(a == b)
dará o tamanho de um int
em C, mas o tamanho de um bool
em C ++.
Em relação ao operador condicional ?:
O operador condicional ?:
é um operador estranho com algumas peculiaridades. É um erro comum acreditar que é 100% equivalente a if() { } else {}
. Não é bem assim.
Há um ponto de sequência entre a avaliação do 1º e do 2º ou 3º operando. O ?:
operador é garantido apenas para avaliar tanto o 2º ou o 3º operando, por isso não pode executar quaisquer efeitos colaterais do operando que não é avaliado. Código como true? func1() : func2()
não será executado func2()
. Por enquanto, tudo bem.
No entanto , existe uma regra especial que afirma que o segundo e o terceiro operando devem ser implicitamente promovidos e equilibrados entre si com as conversões aritméticas usuais . ( Regras implícitas de promoção de tipo em C explicadas aqui ). Isso significa que o segundo ou terceiro operando sempre será pelo menos tão grande quanto um int
.
Portanto, não importa isso true
e false
seja do tipo int
C, porque a expressão sempre daria pelo menos o tamanho de um int
não.
Mesmo se você reescrevesse a expressão, ela retornaria o tamanho de um !sizeof(a ? (bool)true : (bool)false)
int
Isso ocorre devido à promoção implícita de tipo por meio das conversões aritméticas usuais.
sizeof(true)
esizeof(false)
também é 4: ide.geeksforgeeks.org/O5jvuN