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
上面的例子。)
作为一个具体的例子,有一个 C++ 实现,其中指向单字节元素的指针大于指向多字节元素的指针,因为硬件使用字(而不是字节)寻址。为了模拟字节指针,C++ 使用硬件指针加上额外的字节偏移量。
void*
存储额外的偏移量,但int*
不存储。转换int*
为char*
作品(因为它必须符合标准),但char*
会int*
丢失该偏移量(您的注释隐含地允许)。
Cray T90 超级计算机就是这种硬件的一个例子。
我会看看我是否能找到标准论点,为什么这对于兼容的 C++ 编译器来说是有效的;我只知道有人这样做了,并不是说这样做是合法的,而是该注释暗示它是合法的。
规则将在 to-from void 指针转换规则中。您引用的段落隐含地将转换的含义转发到那里。
“指向 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*
转换文本使之成为一个完整的语言律师上级应答。
归档时间: |
|
查看次数: |
198 次 |
最近记录: |