是否有任何用例依赖于C中两个分配的整数表示? [英] Are there any use cases relying on integer representation of two allocations being different in C?

查看:87
本文介绍了是否有任何用例依赖于C中两个分配的整数表示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,考虑以下C代码片段:

For example, consider the following C code snippet:

void *p = malloc(1);
void *q = malloc(1);

bool question = (uintptr_t) p == (uintptr_t) q;

我希望每个人都期望question始终为假. (令人惊讶的是,尽管C11标准没有要求.uintptr_t的唯一限制是例如((void *) ((uintptr_t) p)) == p.有关详细信息,请参见C11标准的7.20.1.4.)

I expect everyone expects question be always false. (Surprisingly, the C11 standard does not require it, though. The only restriction on uintptr_t is e.g. ((void *) ((uintptr_t) p)) == p. See 7.20.1.4 of the C11 standard for details.)

我的问题是:是否有任何实际的用例实际上依赖于保证question为假,或更笼统地说,两个分配的整数表示是不同的?

My question is: is there any realistic use case that actually relies on the guarantee that question be false, or more generally, the integer representations of two allocations be different?

推荐答案

问题是有缺陷的.首先,考虑以下代码(我们假设malloc不会返回null):

The question is flawed. First, consider this code (where we suppose that malloc does not return null):

void *p = malloc(1);
void *q = malloc(1);

bool question = (uintptr_t) p == (uintptr_t) q;

根据C 2011标准的uintptr_t规范,如果我们这样做:

Per the C 2011 standard’s specification of uintptr_t, if we do:

void *p1 = (void *) (uintptr_t) p;
void *q1 = (void *) (uintptr_t) q;

然后,p1必须比较等于p,并且q1必须比较等于q.并且,根据==运算符的标准规范,p1q1不得彼此相等,因为它们分别等于pq,因此是指向它们的指针.不同的对象.

Then p1 must compare equal to p, and q1 must compare equal to q. And, per the standard’s specification of the == operator, p1 and q1 must not compare equal to each other, since they are, respectively, equal to p and to q, and hence are pointers to different objects.

因为(void *) (uintptr_t) p(void *) (uintptr_t) q产生不同的值,所以(uintptr_t) p(uintptr_t) q必须是不同的值. (这是因为到void *的转换是C模型中的数学函数.每次在C规则内给定特定值时,它在C规则内产生的结果实际上是相同的. ),因此(uintptr_t) p不等于(uintptr_t) q.

Because (void *) (uintptr_t) p and (void *) (uintptr_t) q produce different values, (uintptr_t) p and (uintptr_t) q must be different values. (This is because the conversion to void * is a mathematical function within the C model. Every time it is given a specific value, within the rules of C, it produces a result that is effectively the same, within the rules of C.) Therefore (uintptr_t) p is not equal to (uintptr_t) q.

现在考虑以下代码,我们将void *更改为char *:

Now consider this code, where we change void * to char *:

char *p = malloc(1);
char *q = malloc(1);

bool question = (uintptr_t) p == (uintptr_t) q;

uintptr_t的规范没有提及char *的转换.显然,这些指向char *的指针可以转换为void *.但是,我看不到该标准要求从char *uintptr_t的转换必须隐式地插入到void *的转换,或者像它那样工作.因此,我认为该标准在技术上是未定义的.但是我怀疑您会发现任何C实现都不同于void *版本,除了专门为违反此实现而构造的版本.

The specification of uintptr_t is silent about conversions from char *. Obviously, these pointers to char * can be converted to void *. However, I do not see that the standard requires that a conversion from char * to uintptr_t must implicitly insert a conversion to void * or act as if it did. So I suppose this is technically undefined by the standard. But I doubt you will find any C implementation in which this differs from the void * version, except one constructed specifically to violate this.

尽管如此,实际上,每个使用uintptr_t的程序员都希望结果完全标识出原始指针(它包含所有要转换回原始指针的信息),因此他们希望uintptr_t结果与之不同.所有不同的指针.

Nonetheless, effectively every programmer that uses uintptr_t expects the result to fully identify the original pointer (it contains all the information to convert back to the original pointer), and hence they expect the uintptr_t result to differ from that of all different pointers.

对于一个特定的示例,macOS中的Accelerate框架期望将不同的指针转换为uintptr_t的结果会产生不同的结果,我相信macOS的许多其他部分也会这样做.

As for one specific example, the Accelerate framework in macOS expects the result of converting different pointers to uintptr_t to produce different results, and I am sure many other parts of macOS do too.

这篇关于是否有任何用例依赖于C中两个分配的整数表示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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