int *pt = 0;
long i = reinterpret_cast<long>(pt);
我保证为0吗?这是定义明确的还是实现定义的?我检查了 c++ 标准,但它只说明
指向数据对象或函数的指针(但不是指向成员的指针)可以转换为任何大到足以包含它的整数类型。
在这种情况下,pt 不指向任何数据对象。该规则是否适用于本案?
int *pt = 0;
long i = reinterpret_cast<long>(pt);
我保证为0吗?这是定义明确的还是实现定义的?我检查了 c++ 标准,但它只说明
指向数据对象或函数的指针(但不是指向成员的指针)可以转换为任何大到足以包含它的整数类型。
在这种情况下,pt 不指向任何数据对象。该规则是否适用于本案?
不,i
不一定是任何值。结果是实现定义的。†</sup>
在 C++ 中,指针的表示是实现定义的,包括空指针的表示。当您将整数值零分配给指针时,您将该指针设置为实现定义的空指针值,该值不一定全为零。通过传递性,将该值转换为整数的结果是实现定义的。
不过,更麻烦的是,由 完成的映射reinterpret_cast
无论如何都是实现定义的。因此,即使空指针值全为零,实现也可以随意生成任何它想要的结果。您只能保证在回退时会获得原始值。
话虽如此,引用后的下一句包括注释:
[注意:对于那些知道底层机器的寻址结构的人来说,这并不奇怪。——尾注]
因此,即使不需要特定的映射,您也可以根据实际情况进行有根据的猜测。
†</sup> 假设long
足够大。在 C++0x 中使用uintptr_t
,可选地定义在<cstddef>
.
我不明白为什么它不会。问题是所讨论的整数类型无法保持那么高的值,但如果它是空指针,则没有问题。
是的,它在运行时指向的位置无关紧要;唯一重要的是指针的类型。“到数据对象或函数”只是意味着“常规”对象指针和函数指针(即指向对象代码的指针)都可以重新转换为数字类型。
我认为您上面的代码可以在所有已知的通用平台上安全地存储 0 到“i”。
你想要 reinterpret_cast(pt) 但是是的,这会起作用。reinterpret_cast 与旧的 C 风格转换(长)相同,并假设您知道自己在做什么。