在 C 中混合指向有符号和无符号的指针

问题描述 投票:0回答:1

假设我有一个具有非负值的整数变量和两个指向它的指针——一个有符号指针和一个无符号指针。据我所知,从标准来看,这很好。

6.5

对象的存储值只能由左值访问 具有以下类型之一的表达式:(*) — 类型 与对象的有效类型兼容,——一个合格的 与对象的有效类型兼容的类型的版本,- 一个类型,它是对应于 对象的有效类型,- 有符号或无符号的类型 对应于有效类型的合格版本的类型 object, — 聚合或联合类型,包括以下之一 其成员中的上述类型(递归地包括 子聚合或包含联合的成员),或者 — 字符类型。

(*) 此列表的目的是指定对象可能会或可能不会被别名的情况。

标准保证两个指针在内存中有相同的布局吗?特别是,最后一行是真的吗?

unsigned value = 3;
int *i = (int *)&value;
unsigned *u = &value;

memcmp(&i, &u, sizeof(u)) == 0;

这可能很重要的一个情况是一个可变参数函数,它期望一个

int *
但被传递一个
unsigned *

pointers c99
1个回答
1
投票

简短的回答:这取决于!

可变参数函数对指针做什么很重要。 例如如果它是将值从一个内存位置复制到另一个内存位置,则可以。 即使使用按位和/或/非运算符。

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 是一个非可变参数函数 - 请参阅可变参数函数的定义(在您提出问题之前不知道)。

© www.soinside.com 2019 - 2024. All rights reserved.