"Missing non-virtual thunks" and inheritance order
Asked Answered
H

2

8

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?

Heriot answered 14/4, 2011 at 15:36 Comment(13)
Are you using the same optimization level for linking against a library that you used to compile your library?Gynaecomastia
Have you recompiled the whole program, libs, resource files, pch after the change ()?Boreal
We have a validation build that builds everything fresh every time it gets checked into source control, so yes.Heriot
Or, rather, we do have fixed pre-compiled third-party libraries like Boost, etc, but all our code is rebuilt every time.Heriot
This message could mean that a virtual function is declared, but not defined (or a definition is not linked in). It could be something else though. Could you please quote one of the error message verbatim?Violaceous
-O2 is a common place of problem for some cases. I also faced a problem with this in g++4.4.x compiler.Fiedler
Something to keep in mind is that generally speaking there is no guarantee that you can link code from different c++ compilers or even different versions of the same c++ compiler. They use different conventions to implement c++ features.Picklock
I had some problems with some early versions of gcc and virtual functions. The solution was to reorder the order of appearance of virtual functions and make it the same on all classes. You can check and see if such an issue is the cause of your problems.Stupendous
I would try rebuilding Boost and other third party (static) libraries. If you're dynamically linking you should be relatively safe, I think.Hydromedusa
In a case like this, if you need to stay with -O2, I would try to use a much newer version of gcc. Or try out clang. Then recompile everything including external libraries if possible.Brassard
Thanks for all the suggestions! Unfortunately I don't have access to the codebase anymore, but I'll leave this here in case it helps someone else in the future.Heriot
@ipapadop, that would have been a gross violation of the C++ definition. I'd expect to see something like that in the very first betas of a C++ compiler at the latest.Woodbury
@Woodbury I agree and I only saw it once in my life in some gcc 3.xStupendous
R
1

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.

Rubiaceous answered 29/10, 2012 at 11:42 Comment(0)
C
0

It could be the diamond problem

if so Check this thread

Countersink answered 16/10, 2012 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.