指向不同类型的指针可以有不同的二进制表示吗?

Dan*_*ica 7 c++ pointers language-lawyer bit-representation

我想知道是否允许 C++ 实现以不同方式表示指向不同类型的指针。例如,如果我们有 4 字节大小/对齐int和 8 字节大小/对齐long,是否可以将指向int/ 的指针表示long为对象地址分别右移 2/3 位?这将有效地禁止将指向指针转换为指向long指针int

我问是因为[expr.reinterpret.cast/7]

对象指针可以显式转换为不同类型的对象指针。v对象指针类型的纯右值转换为对象指针类型“指向cv 的 指针T”时,结果为static_­cast<cv T*>(static_­cast<cv void*>(v))

[注7:将指向T1对象类型的“指向”类型的指针转​​换为“指向”T1类型的指针T2(其中T2是对象类型,对齐要求T2不比 更严格T1)并返回到其原始类型type 产生原始指针值。—尾注]

第一句暗示我们可以将指针转换为任意两种对象类型。但是,(非规范性)注释 7 中的移情文本表示对齐在这里也起到了一定的作用。(这就是为什么我想出了这个int-long上面的例子。)

Yak*_*ont 7

是的

作为一个具体的例子,有一个 C++ 实现,其中指向单字节元素的指针大于指向多字节元素的指针,因为硬件使用字(而不是字节)寻址。为了模拟字节指针,C++ 使用硬件指针加上额外的字节偏移量。

void*存储额外的偏移量,但int*不存储。转换int*char*作品(因为它必须符合标准),但char*int*丢失该偏移量(您的注释隐含地允许)。

Cray T90 超级计算机就是这种硬件的一个例子。

我会看看我是否能找到标准论点,为什么这对于兼容的 C++ 编译器来说是有效的;我只知道有人这样做了,并不是说这样做是合法的,而是该注释暗示它是合法的。

规则将在 to-from void 指针转换规则中。您引用的段落隐含地将转换的含义转发到那里。

7.6.1.9 静态转换 [expr.static.cast]

“指向 cv1 void 的指针”类型的纯右值可以转换为“指向 cv2 T 的指针”类型的纯右值,其中 T 是对象类型,而 cv2 与 cv1 具有相同的 cv 限定,或者比 cv1 更高的 cv 限定。如果原始指针值表示内存中一个字节的地址 A 并且 A 不满足 T 的对齐要求,则结果指针值是未指定的。否则,如果原始指针值指向对象 a,并且有一个 T 类型的对象 b(忽略 cv 限定)与 a 的指针可相互转换,则结果是指向 b 的指针。否则,指针值不会因转换而改变。

这表明转换为更对齐的类型会生成一个未指定的指针,但转换为实际上不存在的相等或更少对齐的类型不会改变指针值。

这是允许将指向 4 字节对齐数据的指针转换为指向 8 字节对齐数据的指针导致垃圾。

每个对象不相关的指针转换都需要通过 a 逻辑地往返void*

对象指针可以显式转换为不同类型的对象指针。当对象指针类型的纯右值 v 转换为对象指针类型“指向 cv T 的指针”时,结果为static_­cast<cv T*>(static_­cast<cv void*>(v))

(来自 OP)

涵盖void*T*; 我还没有找到T*,以void*转换文本使之成为一个完整的上级应答。

  • [此类架构的示例](/sf/answers/489038231/) (2认同)