reinterpret_cast什么时候修改位?

Dre*_*ann 10 c++ casting reinterpret-cast

从C++标准:

5.2.10.3

reinterpret_cast执行的映射可能会或可能不会产生与原始值不同的表示.

我已经在这个网站接受过培训,相信并重复这一点. (即使它可能只是琐事).甲reinterpret_castfloat*int*被允许产生不同的位模式.唯一的保证是 - reinterpret_cast返回结果float*将产生原始位模式.

我的问题:这会发生吗?是否有一个现有的,真实的平台或CPU或编译器实际上reinterpret_cast是一个不同的位模式?如果不是,是否有任何地方现实情况reinterpret_cast任何运行时开销?

根据我的经验reinterpret_cast,演员是编译器的指令,而不是运行时.

Che*_*Alf 5

指针原则上可以是不同的尺寸.最大的指针,如果有任何区别(忽略成员指针,谈论实际指针),是char*因为char定义是一个字节,可以是任何地方,没有对齐.void*必须能够代表char*.

int*使用较少位的系统上char*,在该方向上重新解释可能有点冒险.

我想用这些指针(嘿)你可以在标准中找到它.void*对于任何指针都足够大的要求,以及关于对齐的要求:更严格/更大,指向该类型所需的位数越少.但我还没有听说任何现存的系统存在这样的差异.


关于void*能够代表的标准char*:

C++11§3.9.2/ 4:

"
一个指向CV -qualified(3.9.3)或CV -unqualified void可用于指向未知类型的对象.这样的指针应该能够保存任何对象指针.类型的对象CV void*应具有相同的表示和对准要求CV char*

"任何对象指针"隐含地暗示指针的大小不同.


关于指称对齐的Standaredese:

C++11§5.2.10/ 7:

"
对象指针可以显式转换为不同类型的对象指针.当prvalue v类型的"指针T1"被转换为类型"指针CV T2 ",结果is static_cast<CV T2*>(static_cast<CV void*>(v))如果两个T1T2是标准布局类型(3.9)和的对准要求T2并不比那些更严格的T1,或者如果任一类型是void.将"指向T1"的类型的prvalue转换为"指向"的类型T2(其中T1T2是对象类型,并且对齐要求T2不比那些更严格T1)并返回其原始类型,产生原始指针值.未指定任何其他此类指针转换的结果.

值得注意的是,稍后在标准中有一些支持C类型的类派生模拟,这显然与上面末尾的"任何其他"相矛盾:

C++11§9.2/ 20,

"
指向标准布局结构对象的指针,适当地使用a转换reinterpret_cast,指向其初始成员(或者如果该成员是位字段,则指向它所在的单位),反之亦然.

在这种情况下,两个对象必然具有相同的对齐方式,而前面引用的段落只谈到类型的对齐 - 但显然正式的小矛盾并不像我看到的那样是一个实际问题.

  • 我参与了关于Mill CPU的讨论,其中一名团队成员说Ivan Godard正在研究一种"浮点指针"表示,它可以检测*某些*超出界限的访问.在这种情况下,指针的内部表示(在CPU中)将利用未使用的位来表示范围(以某种方式).在讨论中不清楚它们到底有多远,以及它是否可以在CPU外部访问,但至少它们正在考虑它. (2认同)

Jam*_*nze 1

我曾经在char*比 更大的平台上工作过int*,并且在它们具有不同布局的平台上工作过,即使大小相同。然而,这两台机器在今天都没有特别的相关性(尽管第二台 PDP-10其鼎盛时期最重要的机器之一)。还可以想象,本机模式(或以前称为本机模式)的 Intel 上的某些编译模式会“规范化” a 中的指针,reinterpret_cast甚至隐式转换,以便于地址比较。char*也可以想象(尽管我还没有看到),这样的转换会强制执行正确的对齐,例如,从到 的转换 int*可能会强制 2 个低位为 0。但是,实际上,今天,我认为您不应该这样做可能会看到reinterpret_cast数据指针类型之间进行任何更改。这个问题更具历史意义。(但我不确定现代嵌入式处理器。据我了解,它们中的许多都是字寻址,因此如果sizeof(int) != sizeof(char),它们可能需要一种特殊的格式来寻址char。)