题 C ++中bool值的所有可能值是什么?


问题并不像看起来那么明显,而且我很难找到有关该问题的更多信息 bool 输入标准。

根据C ++ 11标准,与此相关的保证是什么 bool 关于的类型:

  • 存储:需要多少空间,忽略对齐?是否需要存储以表示的值 truefalse
  • 取得的价值:让 b 是类型 bool,断言 (b == true) || (b == false) 保持?是 (false < true) 结构良好,是否成立?

33
2017-09-24 14:50


起源


我的第一个猜测是 - 可能的值为true / false,并且可以从int隐式转换(0为假,非零为真)。但我不确定隐式转换为int。 - Tobias Langner
open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf 可能有用。 - Aleph
@AnotherTest:谢谢,我已经查看了标准;) - Laurent LA RIZZA
只是为了好玩: 古典 价值观是 true, false 显然 file not found。看到 thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx ;) - Daniel Frey
@Daniel这个是经典之作: msdn.microsoft.com/en-us/library/office/... - R. Martinho Fernandes


答案:


bool 类型在§3.9.1,基本类型一节中描述。这里的相关内容是第6段的一句话:

类型的值 bool 要么是 true 要么 false47

参考脚注47提供了一些有趣的附加信息:

47) 用一个 bool 以本“国际标准”描述的方式将值定义为“未定义”,例如通过检查未初始化的自动对象的值,可能会使其表现得好像它既不是 true 也不 false

这只是标准对具有未定义行为的程序没有要求的直接结果。

没有尺寸要求 bool,除了作为C ++内存模型的结果适用于所有类型的隐式“至少一个字节”。

对内部表示也没有要求 bool 但是,由于有关积分转换的要求(true 必须转换为 1 和 false 至 0),实现可能倾向于选择相同的表示 true 和 1,并为 false 和 0因为这样就不需要这样的转换了。


41
2017-09-24 14:53



3.9.1 - 7:bool,char,wchar_t和signed和unsigned integer类型的值被集体称为整数类型。积分类型的表示应使用纯二进制计算系统定义值。这基本上意味着bool在内部是一个整数。我认为没有为它定义严格的位数。 - Tobias Langner
@Laurent第3.9段§3.9可能有所帮助。与流行的看法相反,大多数语言不是基于位和字节,而是基于对象和值,它们是位和字节的抽象。 - R. Martinho Fernandes
@SigTerm它并不重要。如果它们小于8位,则C ++不能直接用机器本机的字节实现,几乎所有东西都需要在这些机器上模拟。 - R. Martinho Fernandes
@SigTerm:你可以实现一些东西 类似 至 bool 但不是 bool。特别是来自和你的类型的转换(比如说 int) 将会 用户自定义 转换而不是 整体促销,并且在任何有效的转换序列中最多只能有一个隐式用户定义的转换。你不能替代所有的用途 bool 同 Bool 因为其中一些将无法编译。 - David Rodríguez - dribeas
@David我认为你不能在一个字节中以一种适用于所有理论实现的方式实现可选的<bool>,如果你想提供的话 T& operator*();。病态实施可以假设 所有 可用位模式表示真假之一,每次写入时都是如此 x = true; 随机挑选其中一个 true 图案。这使得你没有稳定的模式来代表你的额外“无”状态。由于您需要使用operator *提供对象的引用,因此您需要有一个 bool 在某个地方。请注意,vector <bool>使用那些可怕的代理来解决这个问题。 - R. Martinho Fernandes


存储:需要多少空间,忽略对齐?

实现定义,但实际上是一个字节。它通常不能更小,因为这是可能的最小对象大小。例外情况是:

  • bitfield类成员可以是一个位;
  • std::vector<bool> 打包值,使每个值占一位;但并不真正持有类型的对象 bool。其他类型(如 std::bitset做类似的事情,但不要假装存储 bool

是否需要存储以表示的值 true 和 false

没有;只是要求转换为数字类型时 true 变成1和 false 在实践中,这意味着实现可能会使用这些值;虽然,在某些平台上,其他表示可能会更好。

取得的价值:让 b 是一个类型的对象 bool,断言 (b == true) || (b == false) 保持?

断言将持有,如果 b 已初始化或分配有效值。如果它没有被初始化,那么它可能不会成立;但是如果使用未初始化的值,则无论如何都有未定义的行为。事实上,该标准包含一个特定的脚注(由C ++ 11 3.9.1 / 6引用)警告:

47)以本国际标准所描述的方式将bool值用作“未定义”,例如通过检查未初始化的自动对象的值,可能会使其表现为既不是真也不是假。

更新:问题不断增长:

(false < true) 结构良好,是否成立?

是的,是的。操作数被提升为 int给予 0 < 1这是真的。


24
2017-09-24 14:55



全面的答案,应该被接受。 - laike9m


关于的大小 bool 如果我们看看部分 5.3.3  SIZEOF 从C ++标准草案中可以看出(强调我的):

sizeof(char),sizeof(signed char)和sizeof(unsigned char)是1.应用于任何其他基本类型(3.9.1)的sizeof的结果是实现定义的。 [注意:特别是 sizeof(bool),sizeof(char16_t),sizeof(char32_t)和sizeof(wchar_t)是实现定义的74  - 尾注] [...]

并且关于价值观 bool 如果我们看看部分 3.9.1  基本类型 段 6 说:

bool类型的值为true或false。47

你还问:

取值:设b为bool类型的对象,断言(b == true)|| (b ==假)持有?是(假<true)格式良好,是否成立?

部分 4.5  整体促销 段落中说 6

bool类型的prvalue可以转换为int类型的prvalue,false变为零,true变为1。

自从操作数到 < 晋升为 int 然后 (false < true) 认为如此 b 正确初始化(你没有调用未定义的行为) 然后 (b == true) || (b == false) 也持有。


7
2017-09-24 14:56





有两个可能的值, true 和 false

您可能观察到的任何其他内容都是未定义行为的结果。


6
2017-09-24 14:54





在正常使用情况下,作为bool转换的所有非零值数据都被解释为true,并且作为bool转换的数据的所有零值都是false。 bool必须至少为1个字节,因为C ++中的所有类型都必须遵守此质量。

但是我在这里得到了启发,而我上面的每个人都应该受到赞扬。在未定义的行为场景(例如未初始化或格式错误的数据)中,bool可以同时为true和false。这种奇怪的行为,但是那些未定义的东西总是很奇怪。谢谢大家的信息。

在评论中: 这个链接 到相关的帖子。


0
2017-09-24 14:55



这并没有真正回答什么价值观的问题 bool 可以有。任何价值 转换 到了 bool 或者是 false 要么 true  - 但是以其他方式得出的价值呢? - Keith Thompson
解释一下差异?在评估点,任何价值,无论其来源如何,都可以被解释为一个博尔。正如我在上面所解释的那样,这种解释是将数据与bool的评估规则联系起来的。 - Will Custode
看到 R. Martinho Fernandes的回答。在存在未定义的行为时,a bool 价值可能都不是 true 也不 false。 - Keith Thompson
看到 这个。可以创建一个bool值,将true与true进行比较 - BЈовић