在将指针转换为uintptr_t之前需要转换为void *吗?反之亦然? [英] Is a conversion to `void *` required before converting a pointer to `uintptr_t` and vice versa?
问题描述
C99标准的 7.18.1.4 部分:
以下类型指定了一个无符号整数类型,其属性是可以将指向
void
的任何有效指针转换为该类型,然后再转换回指向的指针void
,结果将等于原始指针:
The following type designates an unsigned integer type with the property that any valid pointer to
void
can be converted to this type, then converted back to pointer tovoid
, and the result will compare equal to the original pointer:
uintptr_t
uintptr_t
这是否意味着只能将 void *
类型转换为 uintptr_t
并返回,而无需更改原始指针的值?
Does this mean that only void *
types can be converted to uintptr_t
and back without changing the value of the original pointer?
特别是,我想知道是否需要以下代码才能使用 uintptr_t
:
In particular, I would like to know if the following code is required to use uintptr_t
:
int foo = 42;
void * bar = &foo;
uintptr_t baz = bar;
void * qux = baz;
int quux = *(int *)qux; /* quux == foo == 42 */
或者如果C99标准保证此更简单的版本产生相同的效果:
Or if this simpler version is guaranteed by the C99 standard to result in the same effect:
int foo = 42;
uintptr_t bar = &foo;
int baz = *(int *)bar; /* baz == foo == 42 */
在将指针转换为 uintptr_t
以及反之亦然之前是否需要转换为 void *
?
Is a conversion to void *
required before converting a pointer to uintptr_t
and vice versa?
推荐答案
之所以存在该区别,是因为尽管指向 object 的任何指针都可以转换为 void *
,C不需要将函数指针可以转换为 void *
并再次返回!
The distinction exists also because while any pointer to an object can be converted to void *
, C doesn't require that function pointers can be converted to void *
and back again!
对于指向其他类型对象的指针,C标准表示 any 指针可以转换为整数,并且整数可以转换为任何指针,但是这种结果是实现定义的.由于标准规定只有 void *
可来回转换,所以最安全的选择是首先 cast 指向 void *
的指针,因为它可能是当转换为 uintptr_t
时具有不同表示形式的指针也将导致不同的整数表示形式,因此可以想到:
As for pointers to objects of other types, the C standard says that any pointer can be converted to an integer, and an integer can be converted to any pointer, but such results are implementation-defined. Since the standard says that only void *
is convertible back and forth, the safest bet is to cast the pointer to void *
first, as it might be that pointers that have different representations when converted to uintptr_t
will result in a different integer representation too, so it could be conceivable that:
int a;
uintptr_t up = (uintptr_t)&a;
void *p = (void *)up;
p == &a; // could be conceivably false, or it might be even that the value is indeterminate.
这篇关于在将指针转换为uintptr_t之前需要转换为void *吗?反之亦然?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!