Каковы все возможные значения значения bool в С++?
Вопрос не настолько очевиден, как кажется, и мне трудно найти много информации о типе bool
в стандарте.
Согласно стандарту С++ 11, каковы гарантии, связанные с типом bool
в отношении:
- Хранение: сколько места требуется, игнорируя выравнивание? Есть ли какое-либо требование для значения, которое будет сохранено для представления
true
и false
?
- Выбранные значения: пусть
b
имеет тип bool
, выполняется ли утверждение (b == true) || (b == false)
? Является ли (false < true)
хорошо сформированным и удерживает?
Ответы
Ответ 1
bool
описаны в разделе §3.1.1 "Основные типы". Здесь актуальна фраза из пункта 6:
Значения типа bool
равны либо true
, либо false
. 47
В ссылочной сноске 47 представлена дополнительная информация:
47) Использование значения bool
способами, описанными в этом международном стандарте как "undefined", например, путем изучения значения неинициализированного автоматического объекта, может привести к тому, что он будет вести себя как если это не true
и false
.
Это просто прямое следствие стандарта, не требующего никаких требований к программам с поведением undefined.
В bool
нет требований к размеру, кроме неявного "по крайней мере одного байта", который применяется ко всем типам в результате модели памяти С++.
Также нет требований к внутреннему представлению объектов bool
, однако из-за требований интегральных преобразований (true
необходимо преобразовать в 1
и false
в 0
), реализация может быть склонны выбирать те же представления для true
и 1
, и для false
и 0
, так как это делает такие преобразования ненужными.
Ответ 2
Хранение: сколько места занимает, игнорируя выравнивание?
Реализация определена, но на практике один байт. Обычно это не меньше, так как это минимальный размер объекта. Исключения:
- члены класса битполя могут быть одним битом;
-
std::vector<bool>
устанавливает значения пакетов так, чтобы каждый брал один бит; но на самом деле не содержит объектов типа bool
. Другие типы (например, std::bitset
) выполняют аналогичные действия, но не претендуют на хранение bool
.
Есть ли какое-либо требование для значения, которое будет сохранено для представления true
и false
?
Нет; просто требование, что при преобразовании в числовой тип true
становится 1 и false
становится 0. На практике это означает, что реализация может использовать эти значения; хотя на некоторых платформах другие представления могут работать лучше.
Сделанные значения: пусть b
- объект типа bool
, выполняется ли утверждение (b == true) || (b == false)
?
Утверждение будет выполнено, если b
было инициализировано или присвоено допустимым значением. Если он не инициализирован, то он может не выполняться; но у вас есть поведение undefined, если вы используете неинициализированное значение. Фактически, стандарт содержит конкретную сноску (ссылка на С++ 11 3.9.1/6), предупреждающую об этом:
47) Использование значения bool способами, описанными в этом международном стандарте как "undefined", например, путем изучения значения неинициализированного автоматического объекта, может привести к тому, что он будет вести себя так, как будто он не является ни истинным, ни ложным.
ОБНОВЛЕНИЕ: вопрос продолжает расти:
Является ли (false < true)
хорошо сформированным и удерживает?
Да и да. Операнды продвигаются до int
, давая 0 < 1
, что верно.
Ответ 3
В отношении размера bool
, если мы посмотрим на раздел 5.3.3
Sizeof из черновика стандарта С++, он говорит (внимание мое):
[...] sizeof (char), sizeof (подписанный char) и sizeof (unsigned char) равны 1. Результатом sizeof, применяемым к любому другому фундаментальному типу (3.9.1), является реализация -определенной. [Примечание: в частности, sizeof (bool), sizeof (char16_t), sizeof (char32_t) и sizeof (wchar_t) определены с точки зрения реализации. 74 -end note] [...]
и по отношению к значениям bool
, если мы посмотрим на раздел 3.9.1
Фундаментальные типы в параграфе 6 гласят:
Значения типа bool являются либо истинными, либо ложными. 47
Вы также спросили:
Выбранные значения: пусть b - объект типа bool, выполняется ли утверждение (b == true) || (b == false) удержать? Является ли (false < true) хорошо сформированным и выполняется ли оно?
раздел 4.5
Интегральные рекламные акции говорят в пункте 6:
Значение типа bool может быть преобразовано в prvalue типа int, при этом false становится равным нулю, а true становится единым.
Так как операнды до <
продвигаются до int
, то (false < true)
выполняется, полагая, что b
правильно инициализирован (вы не вызываете поведение undefined), тогда также выполняется (b == true) || (b == false)
.
Ответ 4
Есть два возможных значения: true
и false
.
Все, что вы можете наблюдать, является результатом поведения undefined.
Ответ 5
В обычных случаях использования все ненулевые значения данных, отличных как bool, интерпретируются как истинные, а все нулевые значения данных, отличных как bool, являются ложными. Bool должен быть не менее 1 байт, так как все типы на С++ должны соблюдать это качество.
Но я был просвещен здесь, и все выше меня заслуживают наддува. В сценарии поведения undefined (например, неинициализированные или искаженные данные) bool может одновременно быть истинным и ложным. Такое странное поведение, но опять же, что undefined всегда странно. Спасибо всем за информацию.
В комментариях: эта ссылка к соответствующему сообщению.