bool to int konwersja

140

Jak przenośna jest ta konwersja. Czy mogę być pewien, że oba stwierdzenia przejdą?

int x = 4<5;
assert(x==1);

x = 4>5;
assert(x==0);

Nie pytaj dlaczego. Wiem, że to brzydkie. Dziękuję Ci.

pic11
źródło
Dlaczego nie zmienisz pierwszego wyrażenia? Możesz pisać assert(x!=0). Nawet jeśli bool (true) konwertuje portable na int (1), potwierdzenie „not false” ma bardziej czytelne wyrażenie.
harper
1
Dlaczego nie: assert( 4 < 5);iassert(!( 4 > 5));
Martin York
4
@harper: Użycie wymaganej wartości wyrażenia porównania jest całkowicie uzasadnione.
R .. GitHub PRZESTAŃ POMÓC LODOM
@ R._ Gdy pojawia się pytanie, czy konwersja bool-to-int daje rozsądny wynik, nie polegałbym na tym. Gdy autor ma wątpliwości, że ten wymóg jest spełniony, czytelnik może dostać ten sam problem. Zwłaszcza, że ​​wartość x nie jest warunkiem do sprawdzenia, a jedynie wynikiem pośrednim.
harper
3
Prawdopodobnie napisałbym, (4 < 5) ? 1 : 0gdybym naprawdę musiał przekonwertować wartość logiczną na 0 lub 1. Dobry kompilator prawdopodobnie wyprodukuje ten sam kod maszynowy i będzie bardziej przejrzysty dla ludzkiego czytelnika.
ollb

Odpowiedzi:

216
int x = 4<5;

Całkowicie przenośny. Zgodny z normą. booldo intkonwersji jest niejawna!

§4.7 / 4 ze standardu C ++ mówi ( konwersja integralna )

Jeśli typ źródła to bool, wartość falsejest konwertowana na zero, a wartość truejest konwertowana na jeden .


Jeśli chodzi o C, o ile wiem, nie ma to boolw C. (przed 1999), więc booldo intkonwersji jest istotne tylko w C ++. W C, 4<5zwraca intwartość, w tym przypadku wartość jest 1, 4>5 zostanie oszacowana do 0.

EDYCJA: Jens w komentarzu powiedział, C99 ma _Booltyp. boolto makro zdefiniowane w stdbool.hpliku nagłówkowym. truei falsesą również zdefiniowane w makr w stdbool.h.

§7.16 z C99 mówi:

Makro boolrozwija się do _Bool.

[..], truektóra jest interpretowana jako stała całkowita 1, false która jest interpretowana jako stała całkowita 0, [..]

Nawaz
źródło
3
upewnij się, że istnieje boolw C od 1999 roku. Po prostu użyj nagłówka „stdbool.h” i powinien on zostać uwzględniony.
Jens Gustedt
1
Rzeczywiście, sprawdziłem to na kilku kompilatorach i wydaje się, że jest przenośny.
pic11
9
Niezależnie od wersji języka C i dostępności bool/ _Booltyp, operatorów relacyjnych w C produktów int, nie bool. To znaczy, nawet w C99 operatory relacyjne nadal produkują int.
AnT
54

Oznaczyłeś swoje pytanie [C] i [C ++] w tym samym czasie. Wyniki będą spójne dla wszystkich języków, ale struktura odpowiedzi jest inna dla każdego z tych języków.

W języku C twoje przykłady nie mają żadnego związku bool(dotyczy to również C99). W języku C operatory relacyjne nie dają boolwyników. Oba 4 > 5i 4 < 5są wyrażeniami, które generują wyniki typu intz wartościami 0lub 1. Tak więc w przykładach w C. nie ma żadnego „konwersji bool na int”.

W C ++ operatory relacyjne rzeczywiście dają boolwyniki. boolwartości są konwertowane na inttyp, z truekonwertowaniem na 1i falsekonwertowaniem na 0. Gwarantuje to język.

Język PS C ma również dedykowany typ boolowski _Bool(makro-aliasowany as bool), a jego integralne reguły konwersji są zasadniczo takie same jak w C ++. Niemniej jednak nie dotyczy to twoich konkretnych przykładów w C. Po raz kolejny operatory relacyjne w C zawsze dają int(nie bool) wyniki, niezależnie od wersji specyfikacji języka.

Mrówka
źródło
2
Zgadza się, nie ma bool w K&R C. Ponownie oznaczyłem moje pytanie jako C99.
pic11
@ pic11: Nie trzeba było niczego zmieniać. Nie ma to nic wspólnego z K&R ani jakimkolwiek innym C. Mimo że jest boolw C99, operatory relacyjne nadal produkują intw C99, nie bool. Tak więc, jeśli interesują cię operatory relacyjne (jak w twoich przykładach), problem nadal nie ma nic wspólnego bool.
AnT
Teraz rozumiem. Wynik operatora relacji niejawnie konwertowany na int. To prawda w C, C99 i C ++. Ponownie zaatakowany.
pic11
4
@ pic11: Nie, nie rozumiesz. W C, w tym C99, wynikiem operatora porównania jest an int, a nie bool. Nie dochodzi do konwersji.
R .. GitHub PRZESTAŃ POMÓC W LODZIE
Czy jest jakikolwiek zgodny ze standardami sposób, za pomocą którego język mógłby mieć typ, który zachowuje się jak, boolale nie pozwala na pobranie jego adresu? Wiele systemów wbudowanych wykorzystuje tego typu typy (często deklarowane za pomocą identyfikatora bit). Na przykład na PIC średniego zasięgu if (bitVar1) bitVar2=1;byłyby dwie instrukcje; optymalne kodowanie if (byteVar1) byteVar2=1;to co najmniej cztery (w wielu kompilatorach prawdopodobnie pięć). Takie typy mogą zatem zapewnić znaczny wzrost wydajności.
supercat
18

Sekcja 6.5.8.6 normy C mówi:

Każdy z operatorów <(mniejszy niż),> (większy niż), <= (mniejszy lub równy) i> = (większy lub równy) daje 1, jeśli określona relacja jest prawdą i 0, jeśli jest false.) Wynik ma typ int.


źródło
Dzięki za referencje. Wydaje się, że prawda == 1 z powodów historycznych.
pic11
2

Wydaje się, że nie ma problemu, ponieważ rzutowanie int na bool jest wykonywane niejawnie. Działa to w kompilatorze Microsoft Visual C ++, GCC i Intel C ++. Żaden problem ani w C, ani w C ++.

Alex James
źródło
2
„To działa w niektórych przypadkach” nie jest dobrym sposobem na sprawdzenie poprawności, szczególnie w przypadku nieokreślonych wersji tych narzędzi. Wolę podejście w innych odpowiedziach; nie mogą zagwarantować, że dana implementacja jest poprawna, ale mogą zagwarantować, co zrobi poprawna implementacja.
Matthew Przeczytaj