【问题标题】:What is vtable anchoring, and how does it work in a shared object?什么是 vtable 锚定,它在共享对象中如何工作?
【发布时间】:2016-01-21 00:19:33
【问题描述】:

我正在研究 C++ 库的一些问题,并确保应用程序和共享对象之间的类型信息保持一致。我也有兴趣确保 EqualObject 比较有效,这意味着我确实有相同的对象,而不是在 operator==.

This answer 状态将 vtable 锚定在标头中。我不熟悉这项技术。或者我听说过它的另一个名字。

什么是 vtable 锚定,它是如何工作的?


我还知道 GCC 常见问题解答中的 dynamic_cast, throw, typeid don't work with shared libraries

【问题讨论】:

    标签: c++ vtable shared-objects


    【解决方案1】:

    这是一种非标准技术,但问题很清楚:哪个翻译单元应该包含 vtable?如果一个虚拟析构函数没有被内联,它被定义在一个翻译单元中,并且将 vtable 放在那里是一个简单的选择。

    对于可移植代码,这无关紧要。你不会关心重复的 vtables。

    【讨论】:

    • 感谢 MSalter。 "...它 [dtor] 只在一个翻译单元中定义..." - 这是否意味着仅标头源文件应该添加一个实现文件,以确保定义 dtor在一个翻译单元中脱线?或者也许应该在现有的实现文件中提供离线 dtor? (我认为其中之一就是答案所说的)。
    • 继续评论...答案还继续说:"...定义一个虚拟的外联析构函数(它必须是第一个虚函数声明在header)..." - 让 dtor 成为第一个虚函数有什么意义?如果 dtor 是基类中的第一个虚函数,那么派生类可以将它放在任何地方吗?还是派生类也必须将 dtor 列为第一个虚函数? (我以前从未见过这个要求,我很难理解它,因为我不明白它的作用)。
    • @jww:现在我很困惑。你是怎么突然变成了 header-only 的?我以为你有一个真正的 C++ 共享库? “dtor 作为第一个虚函数”有助于使事情更加可预测:它消除了将 vtable 放入定义第一个虚函数的 TU 中的编译器与将 vtable 放入定义 dtor 的 TU 中的编译器之间的差异(两者都是唯一的,但可能不同)。如果这一切都令人困惑,那是因为它主要是编译器制造商的实现细节。正确的可移植 C++ 代码甚至不假设有一个 vtable 开始!
    • “你是怎么突然变成只有标题的” - 是的,一直都是这样(或者在很多情况下,是的)。 “我以为你有一个真正的 C++ 共享库?” - 是的。 “正确的可移植 C++ 代码甚至不假设有一个 vtable 开头” - 是的,同意。但是我们支持回到 GCC 3.0(Fedora 1 是一个测试平台),所以我们必须小心我们所做的事情,因为我们与编译器的个性有关。
    • 这项研究和头发分裂的原因是(1)我们需要知道我们是否可以比较对象并确保我们正在比较实际分配的对象,以及(2)对编译器的警告-提供的非虚拟析构函数;通过基类指针调用delete;以及如何解决它。 (1) 的用例有点烦人——它与 NIST 的业务需求有关;除了使事情复杂化之外,它与 C++ 无关。图书馆是Crypto++
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2016-09-22
    相关资源
    最近更新 更多