是否有任何用例依赖于C中两个分配的整数表示? [英] Are there any use cases relying on integer representation of two allocations being different in 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
.并且,根据==
运算符的标准规范,p1
和q1
不得彼此相等,因为它们分别等于p
和q
,因此是指向它们的指针.不同的对象.
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屋!