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

标签 c++ boolean language-lawyer

对于真值, boolean 值应该转换为 1,否则为 0。然而,这并没有说明它们实际上是如何存储在内存中的。如果我在 bool 中存储一个任意的非零值会发生什么?在将这些转换为整数时,标准是否保证正确的行为?

例如,给定以下程序,

#include <string.h>

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

  return b;
}

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

最佳答案

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

结果可能是在特定的架构中,bool 的值表示仅包含高位,在这种情况下,通过在字节上广播 123 产生的值bool 的结果将是 false 的表示。

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

§3.9.1 [basic.fundamental]/1:

…For narrow character types, all bits of the object representation participate in the value representation. For unsigned narrow character types, each possible bit pattern of the value representation represents a distinct number. These requirements do not hold for other types.

同一节的第 6 段要求 bool 类型的值是 truefalse,但脚注指出面对未定义的行为,bool“可能表现为既非真也非假。” (这显然在未定义行为的范围内;如果一个程序展示了 UB,那么即使在 UB 被证明之前,它的执行也没有任何要求。)

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

关于c++ - 编译器是否应该将 bool 中的任意非零值正确解释为 true?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34522504/

相关文章:

python波浪号一元运算符作为否定numpy bool数组

java - 比较 boolean 值

c - 在标准 C 中从头开始实现 memcpy 在技术上是不可能的吗?

c++ - C++17 中 malloc 返回 "invalid pointer value"吗?

c - scanf 是否保证在失败时不会更改值?

C++动态审查工具

c++ 11将 vector 插入特定位置

c++ - 我可以使用 decltype() 来避免显式模板实例化中的代码重复吗?

arrays - 如何以最轻的大小在文件中存储大量 boolean 值?

c++ - 打开文件时,C 还是 C++?