перетворення від bool до int


131

Наскільки портативно це перетворення. Чи можу я бути впевнений, що обидва твердження проходять?

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

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

Не питайте, чому. Я знаю, що це некрасиво. Дякую.


Чому ти не зміниш першого виразу? Можна писати assert(x!=0). Навіть якщо bool (true) перетворює портативний на int (1), твердження "не помилково" мають більш читабельний вираз.
харпер

1
Чому б і ні: assert( 4 < 5);іassert(!( 4 > 5));
Мартін Йорк

4
@harper: Використання необхідного значення виразу порівняння є цілком розумним.
R .. GitHub СТОП ДОПОМОГАТИ ЛІС

@ R._ Коли питання полягає в тому, якщо конверсія "bool-in-int" дає розумний результат, я б на це не покладався. Коли у автора є сумніви, що ця вимога є повною, читач міг би отримати ту саму проблему. Тим більше, що значення х - не умова перевірки, а лише проміжний результат.
харпер

3
Я б, напевно, писав, (4 < 5) ? 1 : 0якщо мені справді потрібно перетворити булевий у 0 або 1. Хороший компілятор, ймовірно, створить той же машинний код і зрозуміліший для людського читача.
ollb

Відповіді:


205
int x = 4<5;

Повністю портативний. Стандартний відповідник. boolдля intперетворення неявно!

§4.7 / 4 із стандарту C ++ говорить (інтегральне перетворення )

Якщо тип джерела - bool, значення falseперетворюється в нуль, а значення trueперетворюється в одне .


Чи не стосується C, наскільки я знаю , не існує boolв С (до 1999 р) Таким чином , boolдля intперетворення релевантна в C ++ тільки. У C, що 4<5оцінює intзначення, у цьому випадку значення 1, яке 4>5 було б оцінено 0.

EDIT: Єнс у коментарі сказав, що C99 має _Boolтип. boolце макрос, визначений у stdbool.hфайлі заголовка. trueа falseтакож є макрос визначеними в stdbool.h.

§7.16 від C99 говорить:

Макрос boolрозширюється до _Bool.

[..] trueякий розширюється до цілої постійної 1, false яка розширюється до цілої постійної 0, [..]


3
впевнений, що він є boolв C з 1999 року. Просто використовуйте заголовок "stdbool.h", і це слід включити.
Jens Gustedt

1
Дійсно, я перевірив це на декількох компіляторах і, здається, він є портативним.
pic11

8
Незалежно від версії мови C та наявності bool/ _Boolтипу, реляційні оператори в C виробляють int, не bool. Тобто навіть у С99 реляційні оператори все ще виробляють int.
ANT

51

Ви позначали свої питання [C] та [C ++] одночасно. Результати будуть відповідні між мовами, але структура відповіді для кожної з цих мов різна.

На мові C ваші приклади не мають жодного стосунку bool(це стосується і C99). На мові С реляційні оператори не дають boolрезультатів. Обидва 4 > 5і 4 < 5є виразами, які дають результати типу intзі значеннями 0або 1. Отже, у ваших прикладах у C. не відбувається жодного "bool to int converting" будь-якого типу.

У реляційних операторах C ++ справді даються boolрезультати. boolЗначення можна перетворити на intтип, з trueперетворенням у 1та falseперетворення у 0. Це гарантується мовою.

У мові PS C також є виділений булевий тип _Bool(макро-псевдонім як bool), і його інтегральні правила перетворення по суті такі ж, як у C ++. Але все-таки це не стосується ваших конкретних прикладів C. Ще раз: реляційні оператори в C завжди дають int(не bool) результати незалежно від версії мовної специфікації.


2
Це правильно, в K&R C. немає булінгу. Я повторно позначив своє запитання як C99.
pic11

@ pic11: Не потрібно було нічого переназначати. Це не має нічого спільного з K&R або будь-яким іншим C. Хоча там є boolC99, реляційні оператори все ще виробляють intC99, не так bool. Отже, якщо це конкретно реляційні оператори, які вас цікавлять (як у ваших прикладах), проблема все ще не має нічого спільного bool.
ANT

Тепер я розумію. Результат оператора відношення неявно перетворюється на int. Це вірно в C, C99 і C ++. Знову націлено.
pic11

3
@ pic11: Ні, ви цього не розумієте. У C, включаючи C99, результатом оператора порівняння є an int, а не a bool. Конверсія не відбувається.
R .. GitHub СТОП ДОПОМОГАТИ ЛІС

Чи існує спосіб, який відповідає стандартам, завдяки якому мова може мати тип, який поводиться, boolале не дозволяє приймати її адресу? Багато вбудованих систем використовують такі типи (часто декларуються за допомогою ідентифікатора bit). Наприклад, серед PIC середнього класу, if (bitVar1) bitVar2=1;було б дві інструкції; оптимальне кодування для if (byteVar1) byteVar2=1;було б принаймні чотири (на багатьох компіляторах, ймовірно, п'ять). Таким чином, такі типи можуть забезпечити значне підвищення продуктивності.
supercat

17

У розділі 6.5.8.6 стандарту С сказано:

Кожен з операторів <(менше, ніж),> (більше, ніж), <= (менше або дорівнює) і> = (більший або рівний) повинен отримати 1, якщо вказане відношення є істинним, і 0, якщо воно false.) Результат має тип int.


Дякую за довідку. Здається, що правда == 1 з історичних причин.
pic11

2

Здається, немає жодних проблем, оскільки роль int to bool cast робиться неявно. Це працює в компіляторі Microsoft Visual C ++, GCC та Intel C ++. Немає проблем ні в C, ні в C ++.


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