假设我有一个具有非负值的整数变量和两个指向它的指针——一个有符号指针和一个无符号指针。据我所知,从标准来看,这很好。
6.5
对象的存储值只能由左值访问 具有以下类型之一的表达式:(*) — 类型 与对象的有效类型兼容,——一个合格的 与对象的有效类型兼容的类型的版本,- 一个类型,它是对应于 对象的有效类型,- 有符号或无符号的类型 对应于有效类型的合格版本的类型 object, — 聚合或联合类型,包括以下之一 其成员中的上述类型(递归地包括 子聚合或包含联合的成员),或者 — 字符类型。
(*) 此列表的目的是指定对象可能会或可能不会被别名的情况。
标准保证两个指针在内存中有相同的布局吗?特别是,最后一行是真的吗?
unsigned value = 3;
int *i = (int *)&value;
unsigned *u = &value;
memcmp(&i, &u, sizeof(u)) == 0;
这可能很重要的一个情况是一个可变参数函数,它期望一个
int *
但被传递一个unsigned *
。
简短的回答:这取决于!
可变参数函数对指针做什么很重要。 例如如果它是将值从一个内存位置复制到另一个内存位置,则可以。 即使使用按位和/或/非运算符。
E。 G。以上
memcmp(...) == 0
就可以了
但是如果取值来计算,如果在有符号和无符号之间进行解释,某些值是不同的,那么结果当然是不同的。 但是如果以上
memcmp(...) < 0
可能会失败,如果在u和i处找到这样的值对于u的长度。
PS:在您的示例中,
memcmp
之前的代码行是这样的,即 i 和 u 将包含相同的地址,因此该地址的按位表示相同,因此 memcmp(i, u, sizeof(u)) == 0
将始终返回 true!
PS2:但是您使用
memcmp(&i, &u, sizeof(u)) == 0
指向变量 i 和 u 的指针是什么 - 函数 memcmp 比较相等的值(二进制)(因此变量 i 和 u 的内容)。
所以它会返回 true.
评论后:
即使您的第一行“假设我有一个非负值的整数变量并且”不是真的,我的答案也适用。
memcmp
比较内存中的多个字节(按位,二进制),无论两个内存区域的字节是否代表字符,字符串,(无符号)字节/短裤/整数/长或仅其部分 - 作为一些例子.因此,比较区域是表示无符号值还是有符号值并不重要。在您的情况下,无论指针是用于 (unsigend) int 还是其他东西,您都比较指针值 (unsigned int)。 &u 和 &i 都指向内存中相同的 4 个字节,我会说,内存结构是相同的。
但是用 *u 和 *i 读取它们将返回一个不同的值,只有当值是负的作为 signed int 解释时。所以我想说记忆解释会有所不同。
但是 memcmp 不解释任何东西。
据我从标准中可以看出,这很好。 是的,如果值仅为正数(如果解释为带符号的 int)或小于/等于 0x7FFFU,如果解释为无符号的 int。否则,副作用由您负责。
PS3:非可变参数和可变参数方法中的指针参数可能会发生此问题 - memcmp 是一个非可变参数函数 - 请参阅可变参数函数的定义(在您提出问题之前不知道)。