如果值本身未更改,是否允许更改对象的基础字节?
因此,例如,此代码段打印"可能会有所不同吗?
int a = 0;
char b[sizeof(int)];
memcpy(b, &a, sizeof(int));
if (memcmp(b, &a, sizeof(int)) {
printf("differ\n");
}
以下问题让我问这个问题:Is delete allowed to modify its parameter?,请查看问题下方的评论,例如Johannes Schaub撰写的comment:
什么规则禁止更改int的内部位?就我而言 知道,甚至允许实现使int a = 0; / *测试 ' a'现在 /; / 测试位' a'现在* /有两个不同的位 每次
答案 0 :(得分:3)
通常,memcpy
和memcmp
严格按字节工作,因此无法区分。
(C ++ 11)标准的一个阅读似乎表明可能可能int
与另一个(memcmp
)不同,你可以如果允许整数具有对值没有影响的填充字节,则只需从中分配它。
根据您的代码使用int
和类似大小的char
缓冲区似乎是可行的:
int a = 0;
char b[sizeof(int)];
memcpy(b, &a, sizeof(int));
,a
中的填充字节(如果有)以基础值不变的方式进行更改。 可能导致memcmp
失败。
可以在C++11 3.9.1 Fundamental types
:
对于字符类型,对象表示的所有位都参与其中 在价值表示中。对于无符号字符类型,值表示的所有可能位模式表示数字。 这些要求不适用于其他类型。
这允许在非字符类型中填充位,并且标准中没有任何内容明确地防止这些位在任何时候发生变化。
然而,在同一部分中,它将字符和有符号或无符号整数混合成一个"整数类型"类别并声明:
整数类型的表示应使用纯二进制计算系统定义值。 (脚注49)[例子:本国际标准允许积分类型的2的补码,1的补码和带符号的幅度表示。 - 例子]
脚注49状态:
使用二进制数字0和1的整数的位置表示,其中由连续位表示的值是加法的,以1开始,并且乘以2的连续积分幂,除了可能具有最高位的位位置。 (改编自美国国家信息处理系统词典。)
这似乎没有为这些类型中的填充位留下开放的可能性,因为它非常具体地调用连续的位和2的幂,唯一的例外是提到的是高位(用于决定三种可能编码的符号)(a)。
所以我怀疑memcmp
使用相同的内存块和大小memcpy
之后不能立即失败。
当然,这与您链接的问题完全无关,因为有一个介入操作delete
,可以自由更改基础位模式。这种情况与以下情况没有什么不同:
int a = 0;
char b[sizeof(int)];
memcpy(b, &a, sizeof(int));
a = 42; // intervening operation
之后memcmp
几乎保证将两个内存块视为不同。
(a)令人讨厌的是,一个潜在读数允许填充位,同时仍然满足"后续"上面提到的比特和2的幂 - 如果填充比特位于基础比特模式的低端(距离符号最远),则是这样。如果允许那么,是的,memcmp
可以在memcpy
之后立即报告差异。