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

时间:2015-12-15 14:11:15

标签: c pointers casting standards

有两个相关的C标准规则:

C99标准,6.3.2.3

  

指向void的指针可以转换为指向any的指针   不完整或对象类型。指向任何不完整或对象类型的指针   可以转换为指向void的指针,然后再返回;结果应该   比较等于原始指针。

7.20.1.4

  

以下类型指定带有的无符号整数类型   可以将任何有效指向void的指针转换为此类型的属性,   然后转换回指向void的指针,结果将进行比较   等于原始指针:            uintptr_t

这意味着,以下代码符合:

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

但它真的需要两步演员吗?如果执行以下操作,编译器是否会执行隐式中间转换:

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

(好吧,它可能适用于大多数编译器,但我的问题是关于标准符合性)

2 个答案:

答案 0 :(得分:11)

我不会冒险。该标准清楚地表明了允许的内容和不允许的内容。

向您的代码的读者写下uintptr_t s = (uintptr_t)(void*)p;信号,告诉您他们正在做什么。

答案 1 :(得分:1)

任何质量通用的实现都将处理uintptr_t与非空类型之间的转换,就好像它们是通过void*进行转换一样。  该标准将这种情况下的行为以及许多其他涉及指针的行为视为实现质量问题,并期望寻求编写高质量实现的人们能够认识到存在一种明显,明智和有用的方式的情况。使得程序的行为无需标准必须明确地枚举它们。他们还认识到,有可能产生一种符合要求但质量很差甚至无用的实现。

尽管有可能实现一个实现,其中uintptr_t与任何非void指针类型之间的转换以实现者选择的任意方式表现,但是任何生成了这种转换都无法实现的实现的人典型的方式,并且没有记录这种差异的充分原因,应该被认为是破坏者,他们试图通过质量低劣的实施破坏语言。程序员不应感到有任何安抚这种行为的义务;除非或直到看到它的含义,否则它将变得越来越糟,直到该语言完全变得无用为止。