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

Lau*_*ZZA 34 c++ c++11

问题并不像看起来那么明显,而且我很难找到有关bool标准中类型的更多信息.

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

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

R. *_*des 42

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

类型的值booltruefalse.47

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

47)使用bool本国际标准描述的方式中的值为"未定义",例如通过检查未初始化的自动对象的值,可能会使其表现为既不是也不truefalse.

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

除了bool作为C++内存模型的结果适用于所有类型的隐式"至少一个字节"之外,没有大小要求.

也有在内部表示没有任何要求bool的对象,然而,由于有关整体转换的要求(true必须转换到1false0),实现可能会倾向于选择相同的表示,true1,和false0,因为这使得这样的转换不必要.

  • @David我认为如果你想提供`T&operator*();`,你就不能以一种适用于所有理论实现的方式在一个字节中实现可选的<bool>.病态实现可以假设*所有*可用的位模式表示真和假之一,每次你写'x = true;`随机选择一个'true`模式.这使您没有稳定的模式来表示您的额外"无"状态.由于你需要使用operator*提供对象的引用,你需要在某处有一个`bool`.请注意,vector <bool>使用那些可怕的代理来解决这个问题. (4认同)
  • @SigTerm它并不重要.如果它们小于8位,则C++不能直接用机器本机的字节实现,几乎所有东西都需要在这些机器上模拟. (2认同)
  • @SigTerm:你可以实现类似于*bool`而不是`bool`的东西.特别是,从您的类型转换到您的类型(比如说`int`)将是*用户定义的*转换而不是*整数促销*,并且在任何有效的转换序列中最多只能有一个隐式的用户定义转换.你不能用`bool`替换`bool`的所有用法,因为它们中的一些将无法编译. (2认同)

Mik*_*our 25

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

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

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

是否需要存储的值来表示truefalse

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

取值:b设为类型的对象,bool断言是否(b == true) || (b == false)成立?

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

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

更新:问题不断增长:

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

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


Sha*_*our 7

关于bool我们从草案C++标准中看看5.3.3 Sizeof部分的大小,它说(强调我的):

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 == false)举行?是(假<true)格式良好,是否成立?

6段中的4.5 整体促销说明:

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

因为操作数<被提升int然后(false < true)保持假定b正确初始化(你没有调用未定义的行为)然后(b == true) || (b == false)也成立.


Seb*_*edl 6

有两个可能的值,truefalse.

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