我的理解是 C++ reinterpret_cast 和 C 指针转换只是一个编译时功能,它根本没有性能成本。
这是真的?
这是一个很好的假设。但是,优化器可能会在存在reinterpret_cast<>
或 C 指针转换的情况下受到限制。然后,即使强制转换本身没有关联的指令,生成的代码也会变慢。
例如,如果您将 int 转换为指针,优化器可能不知道该指针可能指向什么。因此,它可能不得不假设通过该指针的写入可以更改任何变量。这击败了非常常见的优化,例如将变量存储在寄存器中。
这是正确的。除了在新宽度下执行指令的性能增益/损失之外,没有任何成本,我可能会补充,这只是在极少数情况下的一个问题。在我听说过的每个平台上的指针之间进行转换都是零成本,并且没有任何性能变化。
C++ 中的 C 样式转换将首先尝试 static_cast,并且仅在无法执行静态转换时才执行 reinterpret_cast。在多重继承的情况下(或将接口转换为具体类型时),static_cast 可能会更改指针的值,此偏移量计算可能涉及额外的机器指令。这至多是 1 条机器指令,非常小。
你是对的,但想想看:reinterpret_cast 意味着可能是一个糟糕的设计,或者你正在做一些非常低级的事情。
动态转换反而会让你付出一些代价,因为它必须在运行时查看查找表。
是的,这是真的。具有运行时成本的转换类型是 dynamic_cast。
reinterpret_cast
不会产生运行时成本。但是您必须小心,因为每次使用reinterpret_cast
都是实现定义的。例如,将数组重新解释char
为int
数组可能会导致目标架构抛出中断,因为不同的类型可能有不同的对齐规则。
先正确,再担心效率。
在将签名字符重新解释为无符号字符之前和之后,我都在查看我的汇编代码。指令增加了大约 3 或 4 个指令。
int main()
{
signed char i = 0x80;
(unsigned char&)i >>= 7;
return i;
}
我正在转换为 unsigned char 以使编译器使用 SHL 指令,而不是 SAR 指令,因此新移位的位将是 zer0s 而不是 var i 有符号位值。
编译器仍然并且似乎总是使用 SAR 指令。但是重新解释强制转换使编译器添加了更多指令。还有 3 到 4 条指令!
我担心为什么我将 UTF8 转换为 UTF16 字符串的 unicode 函数比 Win32 MultiByteToWideChar() 慢了近 3 倍。现在我担心选角是主要因素之一。
这很讽刺,因为我们使用重新解释演员来提高速度。