Odlewy w twoim pytaniu są zbędne, czy powinny zostać odwrócone?
GManNickG
9
Nie chodzi mu o to, żeby bool t = true; int n = 1; if (t == n) {...} ;
byli rzucani,
7
@egrunin: Ech, ale true to bool, a 1 to i tak int. :)
GManNickG
1
Tak, chciałem podać typ wartości.
Petruza
2
(int) truejest 1wartością całkowitą, ale coś, co if (pointer)przechodzi przez część wtedy, jeśli pointer != 0. Jedyną rzeczą, którą możesz założyć jako prawdę, jest to false == 0, i true != 0(i trueocenia się, 1gdy zostanie rzucony int)
Luis Colorado
Odpowiedzi:
134
Tak. Odlewy są zbędne. W Twoim wyrażeniu:
true==1
Obowiązuje promocja integralna, a wartość bool zostanie zmieniona na an, inta ta promocja musi dać 1.
Odniesienie: 4.7 [conv.integral] / 4: Jeśli typ źródła to bool... truejest konwertowany na jeden.
@Joshua: trueto słowo kluczowe zdefiniowane przez język. Biblioteka nie może jej przedefiniować. #defines nie mogą zmieniać definicji słów kluczowych.
jalf
21
@jalf: # define's rzeczywiście może definiować systemowe słowa kluczowe. Faza wstępnego przetwarzania kompilacji C jest czysto tekstowa i nie zna słów kluczowych ani ogólnie składni C. Niemniej jednak redefiniowanie słów kluczowych języka jest prawie zawsze złym pomysłem.
Dale Hagglund
2
@jalf. Oni nie są? Zobacz gcc.gnu.org/onlinedocs/cpp/Macros.html i przynajmniej jeden z wpisów w Międzynarodowym konkursie na zaciemniony kod C, w którym kiedyś zadawano pytanie „Kiedy to whilenie zajmuje czasu?” : (Odpowiedź kiedy trwa dwa parametry, bo wtedy, że wejście miał #definedgo printf.)
Ken Bloom
3
C99, §6.10.1 / 1 mówi: „Wyrażenie sterujące włączaniem warunkowym powinno być wyrażeniem stałym w postaci liczby całkowitej, z wyjątkiem: nie powinno zawierać rzutowania; identyfikatory (w tym te leksykalnie identyczne ze słowami kluczowymi) są interpretowane w sposób opisany poniżej;” Chociaż nie jest to określone jako bezpośrednie zezwolenie, to wyraźnie rozważa możliwość makra, które jest „leksykalnie identyczne” ze słowem kluczowym.
Jerry Coffin
2
Aha, i #defines mogą przedefiniować słowa kluczowe. C ++ 1x spowodował zbyt wiele problemów z nowymi słowami kluczowymi, więc wymaganie musiało zostać usunięte.
Joshua
18
Odpowiedź Charlesa Baileya jest prawidłowa. Dokładne sformułowanie ze standardu C ++ to (§4.7 / 4): „Jeśli typ źródła to bool, wartość false jest konwertowana na zero, a wartość true jest konwertowana na jeden”.
Edycja: widzę, że dodał również odniesienie - wkrótce to usunę, jeśli się nie rozproszę i zapomnę ...
Edit2: Z drugiej strony, prawdopodobnie warto zauważyć, że podczas gdy same wartości logiczne zawsze są konwertowane na zero lub jeden, wiele funkcji (zwłaszcza ze standardowej biblioteki C) zwraca wartości, które są „w zasadzie logiczne”, ale są reprezentowane jako ints, które są zwykle wymagane jest tylko zero, aby wskazać fałsz lub niezerowe, aby wskazać prawdę. Na przykład funkcje is * w <ctype.h>wymagają tylko zera lub niezerowej, niekoniecznie zera lub jedynki.
Jeśli rzucisz to na bool, zero zamieni się na fałsz, a wartość niezerowa na prawdę (jak można się spodziewać).
Zgodnie ze standardem przy takim założeniu powinieneś być bezpieczny. Typ C ++ boolma dwie wartości - truei falseodpowiadające im wartości 1 i 0.
Należy zwrócić uwagę na mieszanie boolwyrażeń i zmiennych z BOOLwyrażeniami i zmiennymi. Ten ostatni jest definiowany jako FALSE = 0i TRUE != FALSE, co w praktyce dość często oznacza, że brana jest pod uwagę dowolna wartość różna od 0 TRUE.
Wiele nowoczesnych kompilatorów faktycznie wyświetli ostrzeżenie dla każdego kodu, który niejawnie próbuje rzutować z BOOLdo, booljeśli BOOLwartość jest inna niż 0 lub 1.
Odkryłem, że różne kompilatory zwracają różne wyniki na true. Odkryłem również, że prawie zawsze lepiej jest porównywać bool do bool zamiast int. Te inte mają tendencję do zmiany wartości w czasie, gdy twój program ewoluuje i jeśli przyjmiesz prawdę jako 1, możesz zostać ukąszony przez niezwiązaną z tym zmianę w innym miejscu w kodzie.
To jest niepoprawna odpowiedź dla C ++, podobnie jak truesłowo kluczowe języka ze zdefiniowanym zachowaniem. Jeśli odwołujesz się do powszechnie zdefiniowanego makra, takiego jak TRUE, jest to poprawne.
David Thornley
1
Może moje doświadczenie było z kompilatorami C - spędziłem z nimi mnóstwo czasu przez lata. Chodzi mi jednak o bezpośrednie używanie wyrażeń matematycznych w stwierdzeniach warunkowych. Mieliśmy kod, który sprawdzał, czy przesunięcie bitowe jest różne od zera w if, a następnie ktoś inny wziął tę samą wartość niezerową i założył, że jest to 1 i wysadził w powietrze. Prosta konwersja na true / 1 zapobiegłaby temu.
Michael Dorgan
Ja też widziałem takie zachowania. Trzeba przyznać, że ostatni raz widziałem to około 1999 roku. Używałem GCC. Językiem był C. Mimo to rzeczywiście widziałem takie zachowanie.
bool t = true; int n = 1; if (t == n) {...} ;
(int) true
jest1
wartością całkowitą, ale coś, coif (pointer)
przechodzi przez część wtedy, jeślipointer != 0
. Jedyną rzeczą, którą możesz założyć jako prawdę, jest tofalse == 0
, itrue != 0
(itrue
ocenia się,1
gdy zostanie rzuconyint
)Odpowiedzi:
Tak. Odlewy są zbędne. W Twoim wyrażeniu:
Obowiązuje promocja integralna, a wartość bool zostanie zmieniona na an,
int
a ta promocja musi dać 1.Odniesienie: 4.7 [conv.integral] / 4: Jeśli typ źródła to
bool
...true
jest konwertowany na jeden.źródło
true
to słowo kluczowe zdefiniowane przez język. Biblioteka nie może jej przedefiniować.#define
s nie mogą zmieniać definicji słów kluczowych.while
nie zajmuje czasu?” : (Odpowiedź kiedy trwa dwa parametry, bo wtedy, że wejście miał#defined
goprintf
.)Odpowiedź Charlesa Baileya jest prawidłowa. Dokładne sformułowanie ze standardu C ++ to (§4.7 / 4): „Jeśli typ źródła to bool, wartość false jest konwertowana na zero, a wartość true jest konwertowana na jeden”.
Edycja: widzę, że dodał również odniesienie - wkrótce to usunę, jeśli się nie rozproszę i zapomnę ...
Edit2: Z drugiej strony, prawdopodobnie warto zauważyć, że podczas gdy same wartości logiczne zawsze są konwertowane na zero lub jeden, wiele funkcji (zwłaszcza ze standardowej biblioteki C) zwraca wartości, które są „w zasadzie logiczne”, ale są reprezentowane jako
int
s, które są zwykle wymagane jest tylko zero, aby wskazać fałsz lub niezerowe, aby wskazać prawdę. Na przykład funkcje is * w<ctype.h>
wymagają tylko zera lub niezerowej, niekoniecznie zera lub jedynki.Jeśli rzucisz to na
bool
, zero zamieni się na fałsz, a wartość niezerowa na prawdę (jak można się spodziewać).źródło
Zgodnie ze standardem przy takim założeniu powinieneś być bezpieczny. Typ C ++
bool
ma dwie wartości -true
ifalse
odpowiadające im wartości 1 i 0.Należy zwrócić uwagę na mieszanie
bool
wyrażeń i zmiennych zBOOL
wyrażeniami i zmiennymi. Ten ostatni jest definiowany jakoFALSE = 0
iTRUE != FALSE
, co w praktyce dość często oznacza, że brana jest pod uwagę dowolna wartość różna od 0TRUE
.Wiele nowoczesnych kompilatorów faktycznie wyświetli ostrzeżenie dla każdego kodu, który niejawnie próbuje rzutować z
BOOL
do,bool
jeśliBOOL
wartość jest inna niż 0 lub 1.źródło
Odkryłem, że różne kompilatory zwracają różne wyniki na true. Odkryłem również, że prawie zawsze lepiej jest porównywać bool do bool zamiast int. Te inte mają tendencję do zmiany wartości w czasie, gdy twój program ewoluuje i jeśli przyjmiesz prawdę jako 1, możesz zostać ukąszony przez niezwiązaną z tym zmianę w innym miejscu w kodzie.
źródło
true
słowo kluczowe języka ze zdefiniowanym zachowaniem. Jeśli odwołujesz się do powszechnie zdefiniowanego makra, takiego jakTRUE
, jest to poprawne.