来自C ++标准:
5.2.10.3
reinterpret_cast执行的映射可能会产生,也可能不会产生 表示与原始值不同的表示。
我已经在这个网站接受过培训,相信并重复这一点。 (即使它可能只是琐事)。允许从reinterpret_cast
到float*
的{{1}}生成不同的位模式。唯一的保证是int*
将结果返回reinterpret_cast
将产生原始位模式。
我的问题:这会发生吗?是否存在实际float*
到不同位模式的现有实际平台或CPU或编译器?如果没有,是否存在reinterpret_cast
任何运行时开销的真实情况?
根据我对reinterpret_cast
的所有经验,演员表是编译器的指令,而不是运行时。
答案 0 :(得分:5)
指针原则上可以是不同的尺寸。最大的指针,如果有任何差异(忽略成员指针,谈论实际指针),则为char*
,因为根据定义char
是一个字节,可以是任何地方,没有对齐。 void*
必须能够代表char*
。
在int*
使用比char*
更少的位的系统上,在该方向上重新解释可能会有点风险。
我认为使用这些指针(嘿)你可以在标准中找到它。这是要求void*
足够大以适应任何指针,以及关于对齐的要求:更严格/更大,指向该类型所需的位数越少。但我还没有听说过任何存在这种差异的现存系统。
关于void*
能够代表char*
:
C ++11§3.9.2/ 4:
<强>” 强>
可以使用指向 cv - 限定(3.9.3)或 cv - 不合格void
的指针 指向未知类型的对象。这样的指针应该能够容纳任何物体 指针。 cvvoid*
类型的对象应具有相同的对象 表示和对齐要求为 cvchar*
“任何对象指针”隐含地暗示指针的大小不同。
Standaredese关于指称对齐方式:
C ++11§5.2.10/ 7:
<强>” 强>
可以将对象指针显式转换为不同类型的对象指针。当“指向v
的指针”的prvalueT1
转换为“指向 cvT2
的指针”时,结果is static_cast<
< em> cvT2*>(static_cast<
cvvoid*>(v))
如果T1
和T2
都是标准布局类型(3.9)和对齐方式T2
的要求不比T1
更严格,或者任何一种类型void
。转换类型的prvalue “指向T1
的指针”指向T2
的指针“(其中T1
和T2
是对象类型,对齐位置T2
的要求不比T1
更严格,并且返回原始类型会产生原始指针 值。任何其他此类指针转换的结果都未指定。
值得注意的是,在标准的后期有一些支持C类型的类推导模拟,这显然与上面末尾的“任何其他”相矛盾:
C ++11§9.2/ 20,
<强>” 强>
指向标准布局结构对象的指针(适当地使用reinterpret_cast
转换)指向它 初始成员(或者如果该成员是位字段,则指向它所在的单位),反之亦然。
在这种情况下,两个对象必然具有相同的对齐方式,而前面引用的段落仅讨论了类型的对齐 - 但显然正式的小矛盾并不是一个实际问题,正如我所看到的那样
答案 1 :(得分:1)
我曾在char*
大于int*
的平台上工作,
并且在他们有不同布局的平台上,即使
大小是一样的。这两台机器都没有
然而,今天特别相关(虽然第二,
PDP-10,是其鼎盛时期最重要的机器之一。
它也可以想象英特尔的一些编译模式
本机模式(或以前称为本机模式)会
&#34;正常化&#34; reinterpret_cast
中的指针,甚至是{
隐式转换,以便于地址比较。
它也是可以想象的(尽管我还没有看到它)
转换强制执行正确的对齐,例如转换自
char*
到int*
可能会强制将2个低位设为0
但是,我今天不会想到你可能会这样做
看到reinterpret_cast
在数据指针之间进行任何更改
类型。这个问题更具历史意义。 (但我不确定
现代嵌入式处理器据我了解,其中很多
是单词寻址,所以如果sizeof(int) != sizeof(char)
,他们就是
可能需要一种特殊格式来解决char
。)