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, [..]
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.
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.
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 ++.
„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.
assert(x!=0)
. Nawet jeśli bool (true) konwertuje portable na int (1), potwierdzenie „not false” ma bardziej czytelne wyrażenie.assert( 4 < 5);
iassert(!( 4 > 5));
(4 < 5) ? 1 : 0
gdybym 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.Odpowiedzi:
int x = 4<5;
Całkowicie przenośny. Zgodny z normą.
bool
doint
konwersji jest niejawna!§4.7 / 4 ze standardu C ++ mówi ( konwersja integralna )
Jeśli chodzi o C, o ile wiem, nie ma to
bool
w C. (przed 1999), więcbool
doint
konwersji jest istotne tylko w C ++. W C,4<5
zwracaint
wartość, w tym przypadku wartość jest1
,4>5
zostanie oszacowana do0
.EDYCJA: Jens w komentarzu powiedział, C99 ma
_Bool
typ.bool
to makro zdefiniowane wstdbool.h
pliku nagłówkowym.true
ifalse
są również zdefiniowane w makr wstdbool.h
.§7.16 z C99 mówi:
źródło
bool
w C od 1999 roku. Po prostu użyj nagłówka „stdbool.h” i powinien on zostać uwzględniony.bool
/_Bool
typ, operatorów relacyjnych w C produktówint
, niebool
. To znaczy, nawet w C99 operatory relacyjne nadal produkująint
.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ąbool
wyników. Oba4 > 5
i4 < 5
są wyrażeniami, które generują wyniki typuint
z wartościami0
lub1
. Tak więc w przykładach w C. nie ma żadnego „konwersji bool na int”.W C ++ operatory relacyjne rzeczywiście dają
bool
wyniki.bool
wartości są konwertowane naint
typ, ztrue
konwertowaniem na1
ifalse
konwertowaniem na0
. Gwarantuje to język.Język PS C ma również dedykowany typ boolowski
_Bool
(makro-aliasowany asbool
), 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
(niebool
) wyniki, niezależnie od wersji specyfikacji języka.źródło
bool
w C99, operatory relacyjne nadal produkująint
w C99, niebool
. Tak więc, jeśli interesują cię operatory relacyjne (jak w twoich przykładach), problem nadal nie ma nic wspólnegobool
.int
, a niebool
. Nie dochodzi do konwersji.bool
ale nie pozwala na pobranie jego adresu? Wiele systemów wbudowanych wykorzystuje tego typu typy (często deklarowane za pomocą identyfikatorabit
). Na przykład na PIC średniego zasięguif (bitVar1) bitVar2=1;
byłyby dwie instrukcje; optymalne kodowanieif (byteVar1) byteVar2=1;
to co najmniej cztery (w wielu kompilatorach prawdopodobnie pięć). Takie typy mogą zatem zapewnić znaczny wzrost wydajności.Sekcja 6.5.8.6 normy C mówi:
źródło
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 ++.
źródło