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.
@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).
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.
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.
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.
bool t = true; int n = 1; if (t == n) {...} ;
(int) true
é1
como um valor inteiro, mas algo comoif (pointer)
passa pela parte then ifpointer != 0
. A única coisa que você pode assumir como verdade é quefalse == 0
, etrue != 0
(etrue
avalia1
quando lançado paraint
)Respostas:
Sim. Os elencos são redundantes. Em sua expressão:
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.fonte
true
é uma palavra-chave definida pelo idioma. Não pode ser redefinido por uma biblioteca.#define
s não têm permissão para redefinir palavras-chave.while
não demora?" : (Resposta quando se tem dois parâmetros, porque, então, que a entrada tinha#defined
-aprintf
.)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
int
s 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).fonte
De acordo com o padrão, você deve estar seguro com essa suposição. O
bool
tipo C ++ tem dois valores -true
efalse
com os valores correspondentes 1 e 0.O que se deve observar é misturar
bool
expressões e variáveis comBOOL
expressões e variáveis. Este último é definido comoFALSE = 0
eTRUE != FALSE
, o que muitas vezes na prática significa que qualquer valor diferente de 0 é consideradoTRUE
.Muitos compiladores modernos irão realmente emitir um aviso para qualquer código que implicitamente tentar converter de
BOOL
parabool
se oBOOL
valor for diferente de 0 ou 1.fonte
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.
fonte
true
é uma palavra-chave de linguagem com comportamento definido. Se você se referir a uma macro comumente definida comoTRUE
, ela está correta.