reinterpret_cast 是否比 static_cast 慢?

Is reinterpret_cast any slower than a static_cast?

我正在比较两个 class typedef value_type 的指针,它们都是 T*char16_t.

类型

编译器抱怨我无法比较两者,因为它们是不同的类型:

'some_type1<char16_t>::value_type*' and 'some_type2<char16_t>::value_type*' lacks a cast

奇怪的是,我不能static_cast<>两者之间:

invalid static_cast from type 'some_type1<char16_t>::value_type*' to type 'char16_t*'

我用 reinterpret_cast<> 比较还是只用 static_cast<> 两边和 void* 比较有区别吗?

我在某处读到 reinterpret_cast<> 是在运行时完成的,但我不确定。

更新

我误以为 reinterpret_cast<> 是在运行时完成的。通过进一步讨论,我现在明白它纯粹是一个编译时构造。

奇怪的是,它也被证明 static_cast<> 可以 有运行时成本,其中通过与构造函数匹配将特定对象转换为另一个对象。

例如,您可以将基元 int 转换为具有 static_cast<> 的向量。对于 static_cast<T>(e) 有效的所有情况,这似乎都是正确的。

I read somewhere that reinterpret_cast is done at runtime but I'm not sure.

不,那是错误的(从任何来源得到的)。

reinterpret_cast<>static_cast<> 都在编译时解析(正如您从编译器错误中看到的那样)。

static_cast<>reinterpret_cast<> 稍慢,因为需要在发出的代码中插入一些针对基数 class 的偏移量计算。

可能您将它与确实在运行时完成的 dynamic_cast<> 混淆了,并且执行起来比 reinterpret_cast<>static_cast<>.

慢一点

即使不涉及自定义类型转换逻辑,static_cast 也可能具有(不明显的)运行 时间性能。这是因为在多重继承的情况下,static_cast 需要调整基数的偏移量,这将需要 运行 次算术。虽然效果真的很小,但它确实存在。从下面的代码示例中可以清楚地看出:

struct Mother {
  virtual ~Mother(); 
  virtual void mother();
};

struct Father { 
  virtual ~Father();
  virtual void father();
};

struct Offspring: Mother, Father {
  void mother();
  void father();
};

void foo(Offspring* offspring) {
  Mother* mother = offspring;
  mother->mother();
}

函数 foo() 的 ASM 代码有以下一行:

movq    %rax, -8(%rbp)

这是基础偏移量。如果你移除演员表,你会看到这条线消失。

另一方面,reinterpret_cast 只是真正的编译时转换,在程序 运行 期间没有任何效果。

reinterpret_cast<> 纯粹是编译时转换。您只是在重新解释底层类型是什么,完全回避了类型系统。没有可能的运行时方面。

static_cast<> 可以 有运行时成本,这取决于你static_cast-ing 是什么。如果您要转换 void*,或通过非多态对象层次结构,则不会产生运行时成本。如果您通过多态对象层次结构进行转换,则由于 vtable 必须在运行时发生偏移量更改。

如果您在层次结构之外进行转换,那么您必须实际创建一个新对象。这是否看起来像调用转换函数:

struct A {
    operator B() { /* something */ }
};

A a;
static_cast<B>(a);

或转换构造函数:

static_cast<std::vector<int>>(4);

static_cast<> 创建了一个全新的对象 - 所以肯定需要一些代码 运行 做到这一点!