简体   繁体   English

将非`void`指针转换为`uintptr_t`,反之亦然

[英]Converting a non-`void` pointer to `uintptr_t` and vice-versa

There are two related C standard rules: 有两个相关的C标准规则:

C99 standard, 6.3.2.3 : C99标准, 6.3.2.3

A pointer to void may be converted to or from a pointer to any incomplete or object type. 指向void的指针可以转换为指向任何不完整或对象类型的指针。 A pointer to any incomplete or object type may be converted to a pointer to void and back again; 指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; the result shall compare equal to the original pointer. 结果应该等于原始指针。

And 7.20.1.4 : 并且7.20.1.4

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 to void, and the result will compare equal to the original pointer: uintptr_t 下面的类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将与原始指针进行比较: uintptr_t

It means, that the following code is compliant: 这意味着,以下代码符合:

int *p = NULL;
void *q = (void*)p;
uintptr_t s = (uintptr_t)q;

But does it really need the two-step cast? 但它真的需要两步演员吗? Will the compiler perform an implicit intermediate cast if doing something like: 如果执行以下操作,编译器是否会执行隐式中间转换:

int *p = NULL;
uintptr_t s = (uintptr_t)p;

(Well, it probably will on most compilers, but my question is about standard compliance) (好吧,它可能会出现在大多数编译器上,但我的问题是关于标准符合性)

I wouldn't risk it. 我不会冒险。 The standard makes it abundantly clear what is allowed and what is not allowed. 该标准清楚地表明了允许的内容和不允许的内容。

Writing uintptr_t s = (uintptr_t)(void*)p; uintptr_t s = (uintptr_t)(void*)p; signals to a reader of your code that you know what you're doing. 向你的代码的读者发出信号,告诉你你正在做什么。

Any quality general-purpose implementation will process conversions between uintptr_t and a non-void type as if they'd been converted through void* . 任何高质量的通用实现都将处理uintptr_t和非void类型之间的uintptr_t ,就像它们已经通过void*转换一样。 The Standard treats behavior in this situation, and many others involving pointers, as a quality-of-implementation issue, and expects that people who are seeking to write quality implementations will be able to recognize situations where there's one obvious, sensible, and useful way for a program to behave without the Standard having to explicitly enumerate them all. 标准将这种情况下的行为以及涉及指针的许多其他行为视为实施质量问题,并期望那些寻求编写高质量实施的人能够识别出一种明显,明智和有用的方式。对于程序在没有标准必须明确枚举它们的情况下的行为。 They also recognize that it's possible to produce an implementation which is conforming but of such poor quality as to be useless. 他们还认识到,有可能产生一种符合但质量如此差的实施,以至于无用。

Although it would be possible to have an implementation where conversions between uintptr_t and any non-void pointer type behave in any arbitrary fashion of the implementer's choosing, anyone who produces an implementation where such conversions don't work in the typical fashion, and who fails to document a good reason for such difference, should be recognized as a vandal who is trying to undermine the language with their poor quality implementation. 虽然可以实现uintptr_t和任何非void指针类型之间的uintptr_t以实现者选择的任意方式运行的任何实现,但是任何产生实现的人都会以这种转换方式无法以典型方式工作,并且失败为了记录这种差异的充分理由,应该被认为是一个试图用劣质实施来破坏语言的破坏者。 Programmers should feel no obligation to appease such behavior; 程序员应该没有义务安抚这种行为; unless or until it is seen for what is is, it will get worse and worse until the language becomes totally useless. 除非或直到它被看作是什么,它将变得越来越糟,直到语言变得完全无用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在将指针转换为`uintptr_t`之前是否需要转换为`void *`,反之亦然? - Is a conversion to `void *` required before converting a pointer to `uintptr_t` and vice versa? sizeof(void*)?= sizeof(uintptr_t) 在实践中? - sizeof(void*) != sizeof(uintptr_t) in practice? 将指针转换为数值以进行散列 - 我应该使用 `uintptr_t` 还是 `intptr_t`? - Converting a pointer to a numeric value for hashing - should I use `uintptr_t` or `intptr_t`? 字符数组和 uintptr_t - Char Array and uintptr_t 如果我想对指针进行常规算术(而不是指针算术),我应该使用uintptr_t吗? - If I want to do regular arithmetic (not pointer arithmetic) on a pointer, should I use uintptr_t? C 中 uintptr_t 的自定义实现? - Custom implementatation of uintptr_t in C? 函数指针的指针是否可以转换为void指针,反之亦然? - Is a pointer to function pointer convertible to a void pointer and vice versa? 是否从size_t或uintptr_t来回转换指针会破坏严格的别名? - Does casting a pointer back and forth from size_t or uintptr_t break strict aliasing? 获取变量的十六进制地址为uintptr_t - Get the hexadecimal address of a variable as uintptr_t C - 为什么在进行指针运算时转换为uintptr_t vs char * - C - Why cast to uintptr_t vs char* when doing pointer arithmetic
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM