如果值未更改,是否允许对象的基础字节更改? [英] Are underlying bytes of an object allowed to change, if the value is not changed?

查看:70
本文介绍了如果值未更改,是否允许对象的基础字节更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果值本身未更改,是否允许更改对象的基础字节?

Are underlying bytes of an object allowed to change, if the value itself is not changed?

例如,这个代码片段可以打印不同"吗?

So, for example, can this code-snippet print "differ"?

int a = 0;
char b[sizeof(int)];

memcpy(b, &a, sizeof(int));
if (memcmp(b, &a, sizeof(int)) {
    printf("differ\n");
}

这是让我问这个问题的问题:允许删除进行修改,请查看问题下方的注释,例如,此

Here's the question that made me to ask this: Is delete allowed to modify its parameter?, check out the comments below the question, for example, this comment from Johannes Schaub:

什么规则禁止更改int的内部位?据我 知道,实现甚至可以使int a = 0; /* 测试 现在'a'的位/; /测试位'a'现在*/具有两个不同的位 每次

What rule forbids changing the internal bits of an int? As far as I know, the implementation is even allowed to make int a = 0; /* test bits of 'a' now /; / test bits of 'a' now*/ have two different bits each time

推荐答案

通常,memcpymemcmp严格按字节工作,因此它们不能有所不同.

Generally, memcpy and memcmp work strictly on bytes so they cannot differ.

对(C ++ 11)标准的一次阅读似乎表明可能 与您刚刚分配的另一个(c1>)不同从此开始,如果允许整数具有填充字节,而填充字节对值没有影响.

One reading of the (C++11) standard seems to indicate it may be possible for an int to differ from another (according to memcmp) that you've just assigned it from, if integers are allowed to have padding bytes which have no effect on the value.

按照您的代码,使用int和类似大小的char缓冲区,这似乎是可行的:

It would seem to be feasible as per your code with an int and similarly-sized char buffer:

int a = 0;
char b[sizeof(int)];
memcpy(b, &a, sizeof(int));

,用于a中的填充字节(如果有)以不改变基础值的方式更改. 可能会导致memcmp失败.

for the padding bytes (if any) in a to change in such a way that the underlying value does not change. That could cause a memcmp to fail.

可以在C++11 3.9.1 Fundamental types中找到该特定读物:

That particular reading can be found in C++11 3.9.1 Fundamental types:

对于字符类型,对象表示的所有位都参与 在值表示中.对于无符号字符类型,值表示形式的所有可能的位模式都表示数字. 这些要求不适用于其他类型.

For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types.

这允许在非字符类型内填充位,并且标准中没有明确禁止这些位随时更改的情况.

That allows for the possibility of padding bits within non-character types and there's nothing in the standard explicitly preventing those bits from changing at any time.

但是,在同一部分中,它将字符和有符号或无符号整数集中到整数类型"类别中,并指出:

However, in that same section, it lumps the character and signed or unsigned integers into a "integral type" category and states that the:

整数类型的表示应使用纯二进制计算系统定义值. (脚注49)[示例:本国际标准允许整数类型的2的补码,1的补码和带符号的幅度表示. —完示例]

representations of integral types shall define values by use of a pure binary numeration system. (footnote 49) [Example: this International Standard permits 2’s complement, 1’s complement and signed magnitude representations for integral types. —end example ]

脚注49的状态:

使用二进制数字0和1的整数的位置表示,其中连续位表示的值是加法的,从1开始,然后乘以2的连续积分幂,除了最高位的位可能位置. (改编自《美国国家信息处理系统词典》.

A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position. (Adapted from the American National Dictionary for Information Processing Systems.)

这似乎根本没有给这些类型的填充位打开任何可能性,因为它非常明确地调用了成功位和2的幂,唯一提到的唯一例外是高位(用于确定三种可能的编码的符号)(a).

That doesn't seem to leave the possibility open for padding bits in these types at all, because it very specifically calls out successive bits and powers of two, with the only exception specifically mentioned being the high bit (used for deciding sign for the three possible encodings) (a).

因此,我怀疑memcmp在使用相同的内存块和大小的memcpy之后不会立即失败.

So I suspect that memcmp will not be able to fail immediately following a memcpy using the same memory blocks and size.

当然,这与您链接的问题完全无关,因为有一个中间操作delete,可以随意更改基础位模式.情况与以下情况没有什么不同:

That's totally irrelevant in the question you link to, of course, since there's an intervening operation, delete, which is free to change the underlying bit pattern. That situation is no different to:

int a = 0;
char b[sizeof(int)];
memcpy(b, &a, sizeof(int));
a = 42; // intervening operation

之后,可以保证 将两个内存块视为不同.

after which a memcmp would be pretty much guaranteed to consider the two memory blocks as different.

(a)令人讨厌的是,有一个 潜在读数允许填充位,同时仍满足上述连续"位和2的幂-这就是填充位位于基础位模式的低端(距离符号最远).如果允许使用 ,则可以,memcpy之后的memcmp可以报告差异.

(a) Annoyingly, there is one potential reading allowing for padding bits while still satisfying the "successive" bits and powers-of-two mentioned above - that's if the padding bits are at the low end of the underlying bit pattern (furthest from the sign). If that were allowed then, yes, memcmp immediately after memcpy could report a difference.

这篇关于如果值未更改,是否允许对象的基础字节更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆