“缺少非虚拟重击”和继承顺序

发布于 2024-11-01 03:58:43 字数 519 浏览 1 评论 0原文

我们有一个大型的 C++ 代码库,经过一次小型重构(添加了一个类并重写了一些相关方法)后,我们开始在 GCC 3 和 GCC 3 上遇到链接器错误。 4. 链接器错误具体是在我们的大型 SDK 中子类化的小示例程序中“缺少对非虚拟 thunk 的引用”。

除了一些似乎已经解决的旧 GCC 错误之外,在网络上搜索并没有给出太多提示。

问题的属性似乎是:

  • GCC 3.4.6 & 4.3.3 使用-O2 优化
  • 多重继承,包括偶尔的虚拟继承。
  • 更改继承顺序,例如
    Foo 类:公共 A、公共 B {}
    Foo 类:public B、public A {}
    在缺少的类上,重击“修复”了问题。

虚拟继承仅出现在单个非常常用的基类中,用于引用计数。我已经验证了这个类的每一个用法确实都是虚拟公共的,而不仅仅是偶然的公共继承。

显然摆弄继承顺序并不能真正解决问题。还能是什么?

We have a large code base in C++ and after a smallish refactor (one class added and some related methods rewritten), we started getting linker errors on GCC 3 & 4. The linker errors were specifically "missing references to non-virtual thunks" in small sample programs that subclassed classes in our large SDK.

Searching the web didn't give many hints beyond some old GCC bugs that seem to have been resolved.

The attributes of the problem seem to be:

  • GCC 3.4.6 & 4.3.3 optimizing with -O2
  • Multiple inheritance, including occasional virtual inheritance.
  • Changing the inheritance order from, say,
    class Foo: public A, public B {}
    to
    class Foo: public B, public A {}
    on the classes that are missing the thunks "fixes" the problem.

The virtual inheritance only appears in a single, very-commonly used base class for reference counting. I have verified that every usage of this class really is virtual public, and not just public inheritance by accident.

Obviously fiddling with the inheritance order is not really solving the problem. What else could it be?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏见 2024-11-08 03:58:43

如果更改基类的声明顺序可以解决问题,则可能意味着其中一个基类没有正确定义其声明的内容。

例如,如果您在 A 类中声明了一个(非虚拟)方法 Func,在 B 类中也有相同的声明,但您从未为 A 类定义它,那么第一次在您的子类中调用该方法时,将使用 A 类的版本被调用,但在链接时,找不到引用。
如果更改继承顺序,将使编译器改为调用已定义的 B::Func,然后链接器会找到它。

恕我直言,无论如何,这是一个糟糕的设计,因为行为很难预测和调试。

If changing the declaration order of the base classes fix the issue, it probably means that one of the base class doesn't properly define what it declared.

For example, if you have a declaration with a (not virtual) method Func in class A and the same in class B but you never defined it for class A, then the first time the method is called in your child, the class A's version is called, but at link time, the reference is not found.
If you change inheritance order, will make the compiler call B::Func instead, which is defined and then the linker will find it.

IMHO, it's a bad design anyway, since there behaviour will be hard to predict and to debug.

岁月苍老的讽刺 2024-11-08 03:58:43

如果是的话,可能是钻石问题

请检查这个 线

It could be the diamond problem

if so Check this thread

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文