Posso assumir (bool) true == (int) 1 para qualquer compilador C ++?


118

Posso supor (bool)true == (int)1para qualquer compilador C ++?


3
As projeções em sua pergunta são redundantes, elas devem ser invertidas?
GManNickG

9
Ele não quer que eles sejam bool t = true; int n = 1; if (t == n) {...} ;
moldados

7
@egrunin: Eh, mas true é um bool e 1 é um int de qualquer maneira. :)
GManNickG

1
Certo, eu quis dizer o tipo dos valores.
Petruza

2
(int) trueé 1como um valor inteiro, mas algo como if (pointer)passa pela parte then if pointer != 0. A única coisa que você pode assumir como verdade é que false == 0, e true != 0(e trueavalia 1quando lançado para int)
Luis Colorado

Respostas:


134

Sim. Os elencos são redundantes. Em sua expressão:

true == 1

A promoção integral se aplica e o valor bool será promovido para um int e esta promoção deve render 1.

Referência: 4.7 [conv.integral] / 4: Se o tipo de fonte for bool... trueé convertido para um.


9
@Joshua: trueé uma palavra-chave definida pelo idioma. Não pode ser redefinido por uma biblioteca. #defines não têm permissão para redefinir palavras-chave.
jalf

21
@jalf: #define's têm permissão para definir palavras-chave do sistema. A fase de pré-processamento da compilação C é puramente textual e não conhece palavras-chave ou sintaxe C em geral. No entanto, é claro que quase sempre é uma má ideia redefinir as palavras-chave da linguagem.
Dale Hagglund

2
@jalf. Eles não são? Veja gcc.gnu.org/onlinedocs/cpp/Macros.html , e pelo menos uma das entradas no Concurso Internacional de Código C Ofuscado, que uma vez perguntou "Quando whilenão demora?" : (Resposta quando se tem dois parâmetros, porque, então, que a entrada tinha #defined-a printf.)
Ken Bloom

3
C99, §6.10.1 / 1 diz: "A expressão que controla a inclusão condicional deve ser uma expressão constante inteira, exceto que: não deve conter uma conversão; identificadores (incluindo aqueles lexicamente idênticos às palavras-chave) são interpretados conforme descrito abaixo;" Embora não seja declarado como permissão direta, isso claramente contempla a possibilidade de uma macro que é "lexicamente idêntica" a uma palavra-chave.
Jerry Coffin

2
Ah, e #defines podem redefinir palavras-chave. C ++ 1x causou muitos problemas com suas novas palavras-chave, de modo que esse requisito teve que ser removido.
Joshua

18

A resposta de Charles Bailey está correta. O texto exato do padrão C ++ é (§4.7 / 4): "Se o tipo de origem for bool, o valor falso é convertido para zero e o valor verdadeiro é convertido para um."

Edit: Vejo que ele adicionou a referência também - irei deletar isso em breve, se não me distrair e esquecer ...

Edit2: Mais uma vez, provavelmente vale a pena notar que, embora os próprios valores booleanos sempre sejam convertidos em zero ou um, várias funções (especialmente da biblioteca padrão C) retornam valores que são "basicamente booleanos", mas representados como ints que são normalmente só precisa ser zero para indicar falso ou diferente de zero para indicar verdadeiro. Por exemplo, as funções is * <ctype.h>requerem apenas zero ou diferente de zero, não necessariamente zero ou um.

Se você converter para bool, zero será convertido em falso e diferente de zero em verdadeiro (como você esperaria).


9

De acordo com o padrão, você deve estar seguro com essa suposição. O booltipo C ++ tem dois valores - truee falsecom os valores correspondentes 1 e 0.

O que se deve observar é misturar boolexpressões e variáveis ​​com BOOLexpressões e variáveis. Este último é definido como FALSE = 0e TRUE != FALSE, o que muitas vezes na prática significa que qualquer valor diferente de 0 é considerado TRUE.

Muitos compiladores modernos irão realmente emitir um aviso para qualquer código que implicitamente tentar converter de BOOLparabool se o BOOLvalor for diferente de 0 ou 1.


3

Descobri que diferentes compiladores retornam resultados diferentes em true. Também descobri que quase sempre é melhor comparar um bool com um bool em vez de um int. Esses ints tendem a mudar de valor ao longo do tempo à medida que seu programa evolui e se você assumir como 1 verdadeiro, poderá ser prejudicado por uma alteração não relacionada em outro lugar em seu código.


3
Esta é uma resposta incorreta para C ++, pois trueé uma palavra-chave de linguagem com comportamento definido. Se você se referir a uma macro comumente definida como TRUE, ela está correta.
David Thornley

1
Pode ser que minha experiência tenha sido com compiladores C - passei muito tempo com eles ao longo dos anos. Meu ponto sobre o uso direto de expressões matemáticas em declarações if se mantém. Tínhamos um código que ver se um bit shift era diferente de zero em um if, então outra pessoa pegou o mesmo valor diferente de zero e assumiu que era 1 e explodiu as coisas. Uma simples conversão para true / 1 teria evitado isso.
Michael Dorgan

Eu também vi um comportamento desse tipo. Reconheço que a última vez que o vi foi por volta de 1999. Eu estava usando o GCC. A linguagem era C. Mesmo assim, eu realmente vi esse tipo de comportamento.
THB
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.