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<>
创建了一个全新的对象 - 所以肯定需要一些代码 运行 做到这一点!
我正在比较两个 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<>
创建了一个全新的对象 - 所以肯定需要一些代码 运行 做到这一点!