Чи можу я припустити (bool) true == (int) 1 для будь-якого компілятора C ++?


118

Чи можу я припустити (bool)true == (int)1будь-який компілятор C ++?


3
Записи у вашому питанні зайві, чи слід їх скасовувати?
GManNickG

9
Він не означає, що вони будуть bool t = true; int n = 1; if (t == n) {...} ;
ролями

7
@egrunin: Е-е, але правда - це бул, а 1 - все-таки інт. :)
GManNickG

1
Правильно, я мав на увазі зазначити тип значень.
Петруза

2
(int) trueє 1як ціле значення, але щось, що if (pointer)проходить через тодішню частину, якщо pointer != 0. Єдине, що можна вважати істинним, це те false == 0, що true != 0trueоцінюється, 1коли його подають int)
Луїс Колорадо,

Відповіді:


134

Так. У ролях зайві. У вашому вираженні:

true == 1

Застосовується інтегральна акція, і значення bool буде підвищено до, intі ця акція повинна дати 1.

Довідка: 4.7 [conv.integral] / 4: Якщо тип джерела bool... trueперетворюється на один.


9
@Joshua: trueце ключове слово, визначене мовою. Вона не може бути перероблена бібліотекою. #defines не дозволяють переосмислювати ключові слова.
jalf

21
@jalf: # define's дійсно дозволяється визначати системні ключові слова. Етап компіляції на попередній обробці є чисто текстовим і не знає нічого про ключові слова чи синтаксис С загалом. Тим не менш, майже завжди погана ідея перевизначати мовні ключові слова.
Дейл Хагглунд

2
@jalf. Їх немає? Дивіться сторінку gcc.gnu.org/onlinedocs/cpp/Macros.html та принаймні одну із публікацій Міжнародного конкурсу закордонних кодів C, який одного разу запитав "Коли whileне потрібно час?" : (Відповідь , коли він приймає два параметри, тому що тоді , що запис був #definedйого printf.)
Ken Bloom

3
C99, § 6.10.1 / 1 говорить: "Вираз, який контролює умовне включення, має бути цілим постійним виразом, за винятком того, що: він не повинен містити літери; ідентифікатори (включаючи ті, що лексично ідентичні ключовим словам) інтерпретуються, як описано нижче;" Хоча це не вказано як прямий дозвіл, це чітко передбачає можливість макросу, який "лексично ідентичний" ключовому слову.
Джері Коффін

2
О, і #defines дозволено переглядати ключові слова. C ++ 1x спричинив занадто багато проблем з новими ключовими словами, тому вимогу довелося зняти.
Джошуа

18

Відповідь Чарльза Бейлі правильна. Точне формулювання зі стандарту C ++ є (§4.7 / 4): "Якщо тип джерела - bool, значення false перетворюється в нуль, а значення true перетворюється в одне".

Редагувати: Я бачу, що він також додав посилання - я скоро його видалю, якщо я не відволікаюсь і не забуду ...

Edit2: Знову ж таки, напевно, варто відзначити, що хоча булеві значення завжди перетворюються на нуль або один, ряд функцій (особливо зі стандартної бібліотеки С) повертає значення, які є "в основному булевими", але представлені як ints, які є зазвичай потрібно лише нуль, щоб вказати помилкове або ненульове, щоб вказати істинне. Наприклад, функції * є <ctype.h>лише нульовий або ненульовий, не обов'язково нульовий або один.

Якщо ви призначите це bool, нуль перетвориться на хибне, а ненульове - істинне (як ви очікували).


9

Відповідно до стандарту, ви повинні бути в безпеці з цим припущенням. Тип C ++ boolмає два значення - trueі falseз відповідними значеннями 1 і 0.

На що слід звернути увагу - це змішування boolвиразів та змінних із BOOLвиразом та змінними. Останнє визначається як FALSE = 0і TRUE != FALSE, що досить часто на практиці означає, що вважається будь-яке значення, відмінне від 0 TRUE.

Багато сучасних компіляторів фактично видадуть попередження для будь-якого коду, який неявно намагається BOOLпередати, boolякщо BOOLзначення інше, ніж 0 або 1.


3

Я виявив, що різні компілятори повертають різні результати за правдою. Я також виявив, що майже завжди краще порівнювати bool з bool замість int. Ці вклади, як правило, змінюють значення з часом, коли ваша програма розвивається, і якщо ви вважаєте істинним значення 1, ви можете покусати незв'язаною зміною в іншому місці коду.


3
Це неправильна відповідь для C ++, як trueі мовне ключове слово з визначеною поведінкою. Якщо ви посилаєтесь на загальновизнаний макрос, такий як TRUE, це правильно.
Девід Торнлі

1
Можливо, мій досвід був із компіляторами C - я протягом багатьох років проводив з ними багато часу. Моя думка щодо безпосереднього використання математичних виразів у тому випадку, якщо твердження стоять, хоча. У нас був код, який бачив, якщо зсув біта не нульовий в значенні if, то хтось інший прийняв те саме ненульове значення і припустив, що це 1, і підірвав речі. Просте перетворення на true / 1 завадило б цьому.
Майкл Дорган

Я теж бачив подібну поведінку. Правда, останній раз, коли я це бачив, це було близько 1999 року. Я використовував GCC. Мова була C. Тим не менш, я дійсно бачив таку поведінку.
вт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.