Nei*_*irk 32 c++ memset language-lawyer
假设我有一些遗留代码,除非发现错误,否则无法更改,并且它包含以下代码:
bool data[32];
memset(data, 0, sizeof(data));
Run Code Online (Sandbox Code Playgroud)
这是bool
将数组中的所有false
值设置为值的安全方法吗?
更一般地,是安全的memset
一bool
对0
,以使其价值false
?
是否保证可以在所有编译器上运行?或者我是否要求修复?
Lig*_*ica 24
这是法律保障吗?没有.
C++没有提到bool
值的表示.
它是否由实际现实保证?是.
我的意思是,如果你想找到一个不代表布尔值false
作为零序列的C++实现,我祝你好运.鉴于false
必须隐式转换为0
,true
必须隐式转换为1
,并且0
必须隐式转换为false
,并且0
必须隐式转换为true
......好吧,你以任何其他方式实现它都是愚蠢的.
这是否意味着"安全"是由你来决定的.
我通常不会这样说,但如果我遇到你的情况,我会很高兴让这张幻灯片.如果您真的担心,可以在可安装实际项目之前向可分发项添加测试可执行文件,以验证每个目标平台的前提条件.
不,它不安全(或者更具体地说是便携式).但是,它可能工作凭借的事实,典型的实现将:
memset()
可以处理的元素数组.但是,最佳实践将决定使用bool data[32] = {false}
- 此外,这可能会使编译器在内部以不同的方式内部表示结构 - 因为使用memset()
它可能会导致它生成一个32字节的值数组,而不是比如一个4字节的数据,它将很好地适合在你的平均CPU寄存器内.
从3.9.1/7:
类型bool,char,char16_t,char32_t,wchar_t以及有符号和无符号整数类型统称为整数类型.整数类型的同义词是整数类型.整数类型的表示应使用纯二进制计算系统定义值.
鉴于此,我看不出任何可能的实现bool
,并不代表所有0位的错误.
我相信这个没有具体说明,尽管看起来潜在的表示false
可能都是零.Boost.Container也依赖于此(强调我的):
Boost.Container使用带有零值的std :: memset来初始化某些类型,就像在大多数平台中一样,这个初始化产生了具有改进性能的所需值初始化.
遵循C11标准,Boost.Container假定对于任何整数类型,所有位为零的对象表示应该是该类型中零值的表示.由于_Bool/wchar_t/char16_t/char32_t也是C中的整数类型,因此它将所有C++整数类型视为可通过std :: memset初始化.
他们指出这个C11引用的理由实际上来自C99缺陷:缺陷263:全零位表示增加了以下内容:
对于任何整数类型,所有位为零的对象表示应该是该类型中零值的表示.
那么这里的问题是假设正确,C和C++之间的整数兼容的底层对象表示是什么?提议解决C和C++之间关于整数的对象表示的差异试图在某种程度上回答这个问题,据我所知,这个问题没有得到解决.我在标准草案中找不到确凿的证据.我们有几种情况,它明确地链接到C标准的类型.章节3.9.1
[basic.fundamental]说:
[...]有符号和无符号整数类型应满足C标准第5.2.4.2.1节中给出的约束.
和3.9
[basic.types]说:
类型T的对象的对象表示是由类型T的对象占据的N个无符号字符对象的序列,其中N等于sizeof(T).对象的值表示是保存类型T的值的位集.对于简单的可复制类型,值表示是对象表示中的一组位,用于确定值,该值是实现的一个离散元素 - 定义的值集.44
脚注44(不是规范性的)说:
目的是C++的内存模型与ISO/IEC 9899编程语言C的内存模型兼容.
标准草案中最远的用于指定bool的基础表示的部分是3.9.1
:
类型bool,char,char16_t,char32_t,wchar_t以及有符号和无符号整数类型统称为整数类型.50整数类型的同义词是整数类型.积分类型的表示应使用纯二进制计算系统定义值.[例如:本国际标准允许2的补码,1的补码和积分类型的带符号幅度表示. - 末端的例子]
该部分还说:
bool类型的值为true或false.
但我们都知道的true
和false
是:
布尔文字是关键字false和true.这样的文字是prvalues并且有类型bool.
而且我们知道他们是转换为0
一个1
:
bool类型的prvalue可以转换为int类型的prvalue,false变为零,true变为1.
但这让我们更接近于潜在的表现形式.
据我所知,除了填充位之外,标准引用实际基础位值的唯一位置是通过缺陷报告1796删除的:对于空字符,all-bits-zero是否是一个有意义的要求?:
目前尚不清楚便携式程序可以检查表示的位; 相反,它似乎仅限于检查与值表示相对应的数字位(3.9.1 [basic.fundamental]第1段).要求空字符值比较等于0或'\ 0'而不是指定表示的位模式可能更合适.
有更多的缺陷报告处理标准中的差距,关于值和对象表示之间的差异和差异.
实际上,我希望这可行,我不认为它是安全的,因为我们无法在标准中指出这一点.你是否需要改变它,不清楚,你显然需要进行一些非平凡的权衡.因此,假设它现在有效,那么问题是我们是否认为它可能会破坏各种编译器的未来版本,这是未知的.
归档时间: |
|
查看次数: |
4275 次 |
最近记录: |