将布尔设置为0安全吗?

时间:2015-10-28 00:12:13

标签: c++ language-lawyer memset

假设我有一些遗留代码,除非发现错误,否则无法更改,并且它包含以下代码:

bool data[32];
memset(data, 0, sizeof(data));

这是将数组中的所有bool设置为false值的安全方法吗?

更一般地说,memset bool0是否可以安全地使其值false

是否可以保证适用于所有编译器?或者我是否要求修复?

4 个答案:

答案 0 :(得分:24)

法律是否有保障?否

C ++没有提及bool值的表示。

实际现实是否有保障?是

我的意思是,如果你希望找到一个不代表布尔值false的C ++实现作为一个零序列,我祝你好运。鉴于false必须隐式转换为0,而true必须隐式转换为10必须隐式转换为false,并且非 - 0必须隐式转换为true ......好吧,你以任何其他方式实施它都是愚蠢的。

这是否意味着它安全"是你的决定。

我通常不会这样说,但如果我处于你的情况,我会乐意让这张幻灯片。如果您真的担心,可以在可安装实际项目之前,为可分发项添加测试可执行文件,以验证每个目标平台的前提条件。

答案 1 :(得分:9)

不。这不安全(或更具体地说是便携式)。但是,由于您的典型实现将:

,它可能正常工作
  1. 使用0表示布尔值(实际上,C ++规范要求它)
  2. 生成memset()可以处理的元素数组。
  3. 但是,最佳实践将指示使用bool data[32] = {false} - 此外,这可能会使编译器在内部以不同方式表示结构 - 因为使用memset()可能会导致生成32字节的值数组而不是比如说一个4字节,它可以很好地适应你的平均CPU寄存器。

答案 2 :(得分:7)

从3.9.1 / 7:

  

类型bool,char,char16_t,char32_t,wchar_t,以及签名和   无符号整数类型统称为整数类型。一个   整数类型的同义词是整数类型。的陈述   整数类型应使用纯二进制计数定义值   系统

鉴于此,我无法看到bool的任何可能的实现都不能表示为全0位的错误。

答案 3 :(得分:7)

我认为这个没有说明,尽管false的基本表示似乎可能都是零。 Boost.Container relies on this as well强调我的):

  

Boost.Container使用带有零值的std :: memset来初始化一些   在大多数平台中,这种初始化产生了所需的类型   值初始化,提高了性能。

     

遵循C11标准,Boost.Container假设为任何   整数类型,所有位均为零的对象表示   应该表示该类型的零值。的由于   _Bool / wchar_t / char16_t / char32_t也是C中的整数类型,它认为所有C ++整数类型都可以通过std :: memset初始化。

他们指出这个C11引用的理由实际上来自C99缺陷:defect 263: all-zero bits representations其中添加了以下内容:

  

对于任何整数类型,所有位都是的对象表示   零应该是该类型中零值的表示。

那么这里的问题是假设正确,C和C ++之间的整数兼容的底层对象表示是什么? Resolving the difference between C and C++ with regards to object representation of integers提案在某种程度上试图回答这个问题,据我所知,这个问题没有得到解决。我在标准草案中找不到确凿的证据。我们有几种情况,它明确地链接到C标准的类型。第3.9.1 [basic.fundamental] 部分说:

  

[...]有符号和无符号整数类型应满足   C标准中给出的约束,第5.2.4.2.1节。

3.9 [basic.types] 说:

  

类型T的对象的对象表示是N的序列   由类型T的对象占用的unsigned char对象,其中N等于   的sizeof(T)。对象的值表示是位集   保持类型T的值。对于简单的可复制类型,值   表示是对象表示中的一组位   确定一个值,它是一个离散元素   实现定义的值集。 44

其中脚注44(不是规范)说:

  

意图是C ++的内存模型兼容   ISO / IEC 9899编程语言C.

标准草案在指定 bool 的基础表示时所用的最远位于3.9.1部分:

  

类型bool,char,char16_t,char32_t,wchar_t,以及签名和   无符号整数类型统称为整数类型   整数类型的同义词是整数类型。的陈述   整数类型应使用纯二进制计数定义值   system.51 [例如:本国际标准允许2   补码,1的补码和有符号的幅度表示   整体类型。 - 例子]

该部分还说:

  

bool类型的值为true或false。

但我们所知道的truefalse是:

  

布尔文字是关键字false和true。这样的文字   是prvalues并且有类型bool。

我们知道它们可以转换为01

  

bool类型的prvalue可以转换为int类型的prvalue   假成为零,真正成为一个。

但是这让我们更接近于潜在的表现形式。

据我所知,除了填充位之外,标准引用实际底层位值的唯一位置是通过defect report 1796: Is all-bits-zero for null characters a meaningful requirement? 删除的:

  

不清楚便携式程序是否可以检查表示的位;相反,它似乎仅限于检查与值表示相对应的数字位(3.9.1 [basic.fundamental]第1段)。要求空字符值比较等于0或' \ 0'可能更合适。而不是指定表示的位模式。

有更多defect reports处理标准中的差距,关于值和对象表示之间的差异和差异。

实际上,我希望这会起作用,我不会认为它是安全的,因为我们无法在标准中指出这一点。你是否需要改变它,不清楚,你显然需要进行一些非平凡的权衡。因此,假设它现在有效,我们认为它可能会打破各种编译器的未来版本,这是未知的。