преобразование bool в int


131

Насколько портативно это преобразование. Могу ли я быть уверен, что оба утверждения верны?

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

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

Не спрашивайте почему. Я знаю, что это некрасиво. Спасибо.


Почему бы тебе не изменить первое выражение? Вы можете писать assert(x!=0). Даже если bool (true) преобразует переносимое в int (1), утверждение «not false» имеет более читаемое выражение.
harper

1
Почему бы и нет: assert( 4 < 5);иassert(!( 4 > 5));
Мартин Йорк

4
@harper: совершенно разумно использовать требуемое значение выражения сравнения.
R .. GitHub НЕ ПОМОГАЕТ ICE

@ R._ Когда вопрос в том, дает ли преобразование из логического значения в целое разумный результат, я бы не стал на это полагаться. Когда автор сомневается в выполнении этого требования, читатель может столкнуться с той же проблемой. Тем более, что значение x - это не условие для проверки, а лишь промежуточный результат.
harper

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.

РЕДАКТИРОВАТЬ: Йенс в комментарии сказал, что у C99 есть _Boolтип. boolэто макрос, определенный в stdbool.hфайле заголовка. trueа falseтакже макроопределены в stdbool.h.

В §7.16 от C99 говорится:

Макрос boolрасширяется до _Bool.

[..], trueкоторый расширяется до целочисленной константы 1, false которая расширяется до целочисленной константы 0, [..]


3
уверен, что существует boolна C с 1999 года. Просто используйте заголовок "stdbool.h", и он должен быть включен.
Йенс Густедт

1
Действительно, я проверил это на нескольких компиляторах, и он кажется переносимым.
pic11

8
Независимо от версии языка C и наличия bool/ _Booltype, реляционные операторы в C производят int, not bool. Т.е. даже в C99 реляционные операторы все равно производят int.
AnT

51

Вы одновременно отметили свой вопрос [C] и [C ++]. Результаты будут одинаковыми для разных языков, но структура ответа для каждого из этих языков разная.

На языке C ваши примеры не имеют отношения boolни к чему (это относится и к C99). В языке C реляционные операторы не дают boolрезультатов. Оба 4 > 5и 4 < 5являются выражениями, которые производят результаты типа intсо значениями 0или 1. Итак, в ваших примерах на C. нет никакого «преобразования типа bool в int».

В C ++ операторы отношения действительно дают boolрезультаты. boolзначения могут быть преобразованы в intтип с trueпреобразованием в 1и falseпреобразование в 0. Это гарантируется языком.

PS Язык C также имеет специальный логический тип _Bool(с псевдонимом макроса as bool), а его правила преобразования интегральных функций по существу такие же, как и в C ++. Но, тем не менее, это не имеет отношения к вашим конкретным примерам в C. Еще раз, операторы отношения в C всегда дают int(а не bool) результаты независимо от версии спецификации языка.


2
Правильно, в K&R C. нет bool. Я повторно пометил свой вопрос как C99.
pic11

@ pic11: Не нужно было ничего менять тегами. Это не имеет ничего общего с K&R или любым другим C. Даже несмотря на то, что boolв C99, реляционные операторы все еще производят intв C99, а не bool. Итак, если вас интересуют именно реляционные операторы (как в ваших примерах), проблема все равно не имеет никакого отношения bool.
AnT

Теперь я понимаю. Результат оператора отношения, неявно конвертируемый в int. Это верно для C, C99 и C ++. Снова нацелился.
pic11

3
@ pic11: Нет, ты этого не понимаешь. В C, включая C99, результатом оператора сравнения является intне a bool. Преобразования не происходит.
R .. GitHub ПЕРЕСТАНОВИТЬ ПОМОЩЬ ICE

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

17

В разделе 6.5.8.6 стандарта C говорится:

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


Спасибо за ссылку. Кажется, что true == 1 по историческим причинам.
pic11

2

Кажется, что проблем нет, поскольку приведение типа int к bool выполняется неявно. Это работает в компиляторах Microsoft Visual C ++, GCC и Intel C ++. Нет проблем ни на C, ни на C ++.


2
«В некоторых случаях это работает» - не лучший способ проверить правильность, особенно с неуказанными версиями этих инструментов. Я предпочитаю подход в других ответах; они не могут гарантировать правильность конкретной реализации, но могут гарантировать, что правильная реализация будет делать.
Мэтью Рид
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.