reinterpret_cast何时修改位
When does reinterpret_cast modify bits?
从C++标准:
5.2.10.3
reinterpret_cast执行的映射可能会或可能不会产生 与原始值不同的表示形式。
我在这个网站上接受了培训,相信并重复这一点。 (即使它可能只是琐事(。 允许从 float*
到 int*
的reinterpret_cast
产生不同的位模式。 唯一的保证是,reinterpret_cast
-ing 该结果返回到 float*
将生成原始位模式。
我的问题:这会发生吗? 是否有一个现有的、现实世界的平台或 CPU 或编译器实际上reinterpret_cast
到不同的位模式? 如果没有,是否存在任何reinterpret_cast
运行时开销的实际情况?
根据我所有的reinterpret_cast
经验,强制转换是对编译器的指令,而不是运行时。
指针原则上可以有不同的大小。如果有任何差异(忽略成员指针,谈论真正的指针(,则最大的指针是char*
,因为根据定义,char
是一个字节,可以是任何地方,没有对齐。 void*
必须能够代表char*
。
在int*
使用比char*
少位的系统上,朝这个方向重新解释转换可能有点风险。
我认为通过这些指针(呵呵(,您可以在标准中找到它。这是关于void*
对于任何指针来说足够大的要求,以及关于对齐的事情:越严格/越大,指向该类型的指针所需的位就越少。但我从未听说过任何现存的系统存在这种差异。
关于void*
能够代表char*
的标准:
C++11 §3.9.2/4:
">
可以使用指向符合 cv 条件 (3.9.3( 或不符合 cv 标准的void
的指针 指向未知类型的对象。这样的指针应该能够容纳任何物体 指针。cvvoid*
类型的对象应具有相同的 作为简历char*
的表示和对齐要求
"任何对象指针"模糊地暗示存在不同大小的指针。
关于指称对齐的标准:
C++11 §5.2.10/7:
">
对象指针可以显式转换为不同类型的对象指针。当类型为"指向T1
的指针"的 prvaluev
转换为类型"指向 cvT2
的指针"时,如果T1
和T2
都是标准布局类型 (3.9( 和对齐方式,则结果is static_cast<
cvT2*>(static_cast<
cvvoid*>(v))
T2
的要求并不比T1
严格,或者如果任何一种类型是void
。转换类型的 prvalue "指向T1
的指针"到类型"指向T2
的指针"(其中T1
和T2
是对象类型,其中对齐方式T2
的要求并不比T1
(的要求更严格,并且回到其原始类型,产生原始指针 价值。未指定任何其他此类指针转换的结果。
值得注意的是,在标准后面有一些对类派生的 C 风格模拟的支持,这显然与上面末尾的"任何其他"相矛盾:
C++11 §9.2/20,
">
指向标准布局结构对象的指针,使用reinterpret_cast
进行适当转换,指向其 初始成员(或者,如果该成员是位字段,则到它所在的单元(,反之亦然。
在这种情况下,两个对象必然具有相同的对齐方式,而前面引用的段落只谈到了类型的对齐方式——但在我看来,形式上的小矛盾显然不是一个实际问题。
我曾在char*
大于int*
的平台上工作过,在具有不同布局的平台上,即使大小是一样的。 有问题的机器都不是然而,今天尤其重要(尽管第二个,PDP-10,是鼎盛时期最重要的机器之一(。也可以想象,英特尔上的某些编译模式在纯模式(或过去称为纯模式(将reinterpret_cast
中的指针"规范化",甚至隐式转换,以便于地址比较。也可以想象(虽然我没有见过(这样的转换强制执行正确的对齐方式,例如,从 char*
to int*
可能会强制 2 个低阶位为 0。 在然而,我认为今天你不太可能查看在数据指针之间进行任何更改reinterpret_cast
类型。 这个问题更具历史意义。 (但我不确定现代嵌入式处理器。 据我了解,其中许多人是单词寻址,所以如果sizeof(int) != sizeof(char)
,它们是可能需要一种特殊的格式来寻址char
.(
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 何时在引用或唯一指针上使用移动语义
- 何时提供默认参数作为模板参数
- 独立读取-修改-写入顺序
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- C++-明确何时以及如何调用析构函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我可以通过引用修改常量返回
- 对于结构,表达式必须是可修改的ivalue
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 修改创建帐户程序
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- 如何从子成员函数修改父公共成员变量
- 修改 VS Code 中的默认C++代码段
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 何时需要修改套接字的接收缓冲区大小?
- 何时可以使用 const_cast 删除 const 时修改值
- reinterpret_cast何时修改位