编译器是否应该将bool中的任意非零值正确解释为true?

dra*_*oot 6 c++ boolean language-lawyer

Bool应该转换为1表示真值,否则为0.但是,它没有说明它们实际上如何存储在内存中.如果我在bool中存储任意非零值会发生什么?标准是否保证在将其转换为整数时的正确行为?

例如,给定以下程序,

#include <string.h>

int main()
{
  bool b;
  memset( &b, 123, sizeof( b ) );

  return b;
}
Run Code Online (Sandbox Code Playgroud)

标准是否保证程序将返回1?

ric*_*ici 5

不,在 memset 之后从那个 bool 读取是(至少,见下文)未指定的行为,因此无法保证将返回什么值。

可能会发现在特定架构中, a 的值表示bool仅由高位组成,在这种情况下,通过在 的字节上广播 123 产生的值bool将被证明是false.

C ++标准没有规定什么实际的位模式代表的价值观truefalse是。一个实现可以使用 a 的对象表示中的任何或所有位bool——它必须至少是一个字节,但可能更长——并且它可以将多个位模式映射到相同的值:

§3.9.1 [basic.fundamental]/1:

…对于窄字符类型,对象表示的所有位都参与值表示。对于无符号窄字符类型,值表示的每个可能的位模式代表一个不同的数字。这些要求不适用于其他类型。

同一部分的第 6 段要求 type 的值booltrueor false,但脚注指出,面对未定义的行为,bool“可能表现得好像它既不是 true 也不是 false”。(这显然在未定义行为的范围内;如果程序表现出 UB,则对其执行没有任何要求,即使在 UB 被证明之前也是如此。)

标准中的任何内容都不允许对窄字符数组以外的对象使用低级内存复制操作,除非对象是可简单复制的,并且对象表示通过将其复制到缓冲区来保存,然后通过复制来恢复背部。覆盖对象表示中任意字节的 C 库函数的任何其他使用都应由未定义行为的一般定义(“[标准] 省略行为的任何显式定义”)定义。但是我不得不同意没有明确的声明memset是 UB,因此我将解决未指定的行为,这似乎很清楚,因为 的表示bool肯定是未指定的。

  • @dragonroot:允许未定义的行为这样做。:) (3认同)
  • 你能给出一个标准的引用它是UB吗?术语“陷阱表示”未出现在 C++ 标准中 (2认同)