Czy mogę założyć (bool) true == (int) 1 dla dowolnego kompilatora C ++?


118

Czy mogę założyć (bool)true == (int)1dla dowolnego kompilatora C ++?


3
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.


9
@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ć).


9

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.


3

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.


3
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.
thb
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.