安腾 C++ ABI VTT 内容
Posted
技术标签:
【中文标题】安腾 C++ ABI VTT 内容【英文标题】:Itanium C++ ABI VTT content 【发布时间】:2017-06-09 08:36:00 【问题描述】:我从here(2.6.2) 中了解了 VTT 的结构。但是,我不明白所有元素的目的。
主虚拟指针应该指向 D 的主虚拟表(在 vtable 组中,对吗?)
辅助 VTT 包含在构造时提供给 直接非虚拟 基类(我们称它们为 B)的 VTT。我的理解是,因为这些直接基类 (B) 可能继承自虚拟类,所以这些直接基类 (B) 应该给这些 已经初始化 虚拟类一些其他 vtable,以“让他们相信”他们只是每个 B 的一部分。这是正确的吗?
现在,最后 2 类条目的用途是什么:辅助虚拟指针和虚拟 VTT?我知道继承层次结构中的虚拟类没有被赋予适当的最终 vtable,所以这可能是目的之一。此外,虚拟类可以从其他虚拟类继承自身(考虑 V1 继承自 V2)。然后 V2 再次需要一个特殊的 vtable 来“让它相信”它是 V1 的一部分(当 V1 正在构建时)。
如果您能解释 VTT 中每种条目的确切内容和用途,我将不胜感激。
【问题讨论】:
你了解 C++ 多重继承和虚拟继承、基类初始化的顺序以及复杂对象构建过程中的运行时行为吗?给定一个具有多个基类的类型(可能是虚拟的,也可能不是虚拟的),其中一些声明或定义了一个方法foo
(可能声明或不声明virtual
),你能总是预测哪个确切定义foo
是从所涉及的构造函数之一调用时调用的?包括来自初始化列表的调用?如果您了解语言的复杂性,则更容易理解实现。
我相信我会。但我不明白那个解释的措辞。了解最后两个元素的确切用途(有一个明确的场景)会有所帮助。
"辅助 VTTs" 没有这样的东西,AFAIK
【参考方案1】:
Liskov 可替换性意味着派生类必须在可以接受基类的任何地方都可用。在 C++ 中,这意味着您可以将 Derived
对象的地址传递给采用 Base*
的函数。
现在,在构建复杂对象期间,您可能会遇到*this
根据 C++ 规则是这样的派生对象(因为 Derived
ctor 已成功运行),因此您必须能够将*this
传递给期望Base*
的函数。
但是对于多重和虚拟继承,您需要额外的预防措施。 Base*
必须指向 Base
子对象。在 Itanium ABI 中,该基本子对象必须有一个 vtable 指针,该指针正确地描述了部分构造的对象的行为。这种行为完全取决于哪些部分是构造的,哪些不是构造的。
虽然可以部分构造对象,但其粒度只是类级别。调用的最派生构造函数确切地确定将运行哪些基类构造函数(这不取决于运行时行为)。这些中的每一个要么已经运行,要么没有运行。
因此,一个可行的实现是在每个基类子对象(可能重叠)中有一组虚表和一组虚表指针,并在每个构造函数成功完成时设置虚表指针。
虚拟基类与虚拟函数没有明显的关系,但得名于您可以将虚拟基类偏移量存储在 vtables 中。当您将Derived* this
传递给采用Base*
的函数时,需要此偏移量,其中Base
类型是Derived
的虚拟基类。 (当它是一个常规基类时,你会使用 fixed 偏移量,并且该偏移量甚至可以为零)
【讨论】:
我知道这些信息,但我不明白 VTT 中最后两种类型的元素是什么意思。如果我要创建一个对象,我会这样做:找到虚拟基的拓扑排序。按此顺序创建虚拟基础(但对于从 V2 派生的每个虚拟基础 V1,也是虚拟的,我需要让 V2 在创建 V1 时认为它是 V1 对象的一部分)。完成虚拟基地后,我可以继续指导非虚拟基地。我实例化它们,给它们一个辅助 VTT(这样它们就可以“欺骗”它们的虚拟基地)。 在这种情况下,我需要 VTT 中的最后两种类型来做什么? @user42768:我可能在你的描述中遗漏了一些东西,但你到底打算在哪里进行这样的排序?请记住,基类可能不知道派生类。特别是,一个类甚至可能不知道它会被用作虚拟基类,实际上这可能因用途而异。派生类可能有两个虚拟基类,并且应该能够充当其中任何一个。您希望它如何仅与单个虚拟表一起使用? 在派生类的“负责”构造函数(或者无论如何调用它)中,这种排序应该决定首先创建哪些虚拟基。我知道我们必须有更多的虚拟表,这不是我难以理解的。我不知道最后两种类型是什么意思。辅助虚拟指针是否实际上在 vtable 组中指向它们所引用的特定类的特定位置?另外,这些类到底是哪些?虚拟 VTT 有什么用途? @user42768 “给他们一个辅助 VTT” 甚至还有“辅助 VTT”之类的东西吗?以上是关于安腾 C++ ABI VTT 内容的主要内容,如果未能解决你的问题,请参考以下文章
Eclipse 是不是必须处理 C++ ABI 兼容性问题?