为啥gcc实现的VTT中有top_offset?
Posted
技术标签:
【中文标题】为啥gcc实现的VTT中有top_offset?【英文标题】:Why is there a top_offset in VTT implemented by gcc?为什么gcc实现的VTT中有top_offset? 【发布时间】:2018-10-23 07:52:39 【问题描述】:这是票数最高的答案中的detailed description of VTT。但答案没有解释为什么 VTT 中有top-offset
。
从我的角度来看,当我们down_cast
一个base
指针指向derived
指针时,编译器已经知道offset
需要在编译时调整(当有没有虚推导),因此在以下情况下无需存储top_offset
:
class A
public:
int a;
;
class B
public:
int b;
virtual void w();
;
class C : public A, public B
public:
int c;
;
在这种情况下,C 类型的对象的布局如下(数字假设为 32 位指针):
+-----------------------+
| 0 (top_offset) |//why?
+-----------------------+
c --> +----------+ | ptr to typeinfo for C |
| vtable |-------> +-----------------------+
+----------+ | A::v() |
| a | +-----------------------+
+----------+ | -8 (top_offset) |//why?
| vtable |---+ +-----------------------+
+----------+ | | ptr to typeinfo for C |
| b | +---> +-----------------------+
+----------+ | B::w() |
| c | +-----------------------+
+----------+
为什么在这种情况下VTT中有top_offset
?我认为top_offset
和virtual base offset
只需要在虚拟继承中。
【问题讨论】:
只需 google “c++ 多重继承 top_offset” 即可获得点击率。 @HansPassant 我用谷歌搜索了,但没有找到预期的答案。 @bigxiao 嗯?无论当前代码是否需要某个特定部分,vtable 仍然需要相同的布局。 @bigxiao o11c 写的是 vtable 需要相同的 layout,而不是完全一样。显然需要相同的布局:使用B
的代码将被编译为使用一种在运行时无法更改的特定布局。该布局包括顶部偏移量。
@bigxiao 对于代码通过引用获取B
并使用vtable 中的任何内容,如果它不知道它是普通B
还是B
-in-C
,如何如果它不知道 vtable 布局,它可以使用 vtable 吗?
【参考方案1】:
void *top(B *b) return dynamic_cast<void *>(b);
编译器无法在编译时确定正确的偏移量是多少。可以使用空指针、指向完整B
对象的指针或指向B
子对象的指针调用此函数。这三种情况需要区别对待。 vtable 中的偏移量是允许它工作的原因。
【讨论】:
所以 vtable 中的top_offset
用于这种特殊情况,因此 vtable 中需要 top_offset
。但在大多数情况下,top_offset
是在编译时直接确定的,而不是由一个在 vtable 中?
@bigxiao 确实。在那些可以在编译时确定所需偏移量的情况下,我想不出编译器会从 vtable 加载偏移量的任何原因。
但是 “vtable 中的偏移量是允许它工作的原因。” 似乎不正确。它是 vtable 中的 type_info
对象允许 dynamic_cast
工作。有了type_info
,人们总能知道B* b
的真实类型,从而知道对应的top_offset
,而vtable 中没有top_offset
项。
@bigxiao 假设给定两种类型(本例中为B
和C
),可以确定一种在另一种中的偏移量。这在编译时通常是正确的,但在运行时您最终需要再次使用相同的偏移量。此外,在“钻石问题”(同一个基类被多次继承)的情况下,即使在编译时也无法确定。
菱形问题应该在编译时确定。但是,无论如何,我同意在使用dynamic_cast
到void*
时在vtable中使用top_offset
更方便。跨度>
以上是关于为啥gcc实现的VTT中有top_offset?的主要内容,如果未能解决你的问题,请参考以下文章
gcc std::unordered_map 实现速度慢吗?如果是这样 - 为啥?
如何在 tvOS 中将外部 .vtt 字幕文件添加到 AVPlayerViewController
为啥 GCC 为 C++ <cmath> 实现 isnan() 比 C <math.h> 更有效?