vTable Issue on Linking

InfernalSpoon
Posts: 2
Joined: Sat May 22, 2010 1:24 pm

vTable Issue on Linking

Post by InfernalSpoon »

Hi,

for my project i've switched from the older 2.75 to the newest svn edition of 2.76 but all of a sudden i get this errors when i try to link my stuff

Code: Select all

g++ -bundle SIM_SolverBullet.o SIM_BulletData.o SIM_SolverBulletState.o Gdp_Condition.o   -lbulletdynamics  -lbulletcollision -lbulletmath      -Wl,-rpath,/Library/Frameworks/Houdini.framework/Versions/10.0.390/Libraries -L/Library/Frameworks/Houdini.framework/Versions/10.0.390/Libraries -L/opt/sidefx/hfs10.0.390FS/Frameworks/Houdini.framework/Versions/10.0.390/Libraries -F/opt/sidefx/hfs10.0.390FS/Frameworks -framework Houdini -arch x86_64 -fobjc-gc-only -framework OpenGL -framework Cocoa   -o SIM_SolverBullet.dylib_darwin_10.0.390
Undefined symbols:
  "btCollisionShape::getContactBreakingThreshold(float) const", referenced from:
      vtable for btGImpactShapeInterfacein SIM_SolverBullet.o
  "btTypedConstraint::serialize(void*, btSerializer*) const", referenced from:
      vtable for btTypedConstraintin SIM_SolverBullet.o
      vtable for btTypedConstraintin SIM_SolverBulletState.o
  "btCollisionShape::serializeSingleShape(btSerializer*) const", referenced from:
      vtable for btGImpactShapeInterfacein SIM_SolverBullet.o
  "btCollisionShape::serialize(void*, btSerializer*) const", referenced from:
      vtable for btGImpactShapeInterfacein SIM_SolverBullet.o
ld: symbol(s) not found
i've tried switching arround the order of the libraries to link, but without luck.

any ideas how to fix this ?

thanks!
Infernal
dangerdaveCS
Posts: 14
Joined: Mon Jun 07, 2010 5:37 am

Re: vTable Issue on Linking

Post by dangerdaveCS »

I got the same problem using MS Visual Studio 2008. I tried re-ordering the libraries like you said, and still got the errors. However, then I did a 'Clean Solution' and rebuilt everything and it worked. So it looks like some .obj's weren't being recompiled after the library reshuffle that needed to be.

Considering you're not using Visual Studio I don't know if any of that has any relevance, but just in case... Good luck.
denito
Posts: 4
Joined: Mon Jun 14, 2010 9:30 pm

Re: vTable Issue on Linking

Post by denito »

I believe this can also happen when you have a base class with a function defined like

Code: Select all

virtual some_func()=0;
and you have a derived class that should provide a body for the definition of the function but the function body is missing. This can happen if the function definition really is missing, or maybe the compiler just didn't build the object file where it is (which is why a clean & build sometimes fixes the problem).

The vtbl is a hidden part of the class that holds pointers to a class's virtual methods. It's an array of pointers, and the array has to be placed in one and only one object file; it has to go somewhere but you can't have duplicates of it. But where to put it? C++ doesn't enforce that a class be placed in any particular file (it's not like Java which requires each class to have a file). So the compiler sticks the vtbl in at whichever file is first place where a virtual method is defined. Sometimes the compiler gets confused and thinks it has already put the vtbl in somewhere else when it hasn't (which is when the problem is with the compiler). Other times it is because you declared a virtual method but forgot to define any virtual methods for the class, in which case the problem is with you and you need to provide a definition for the virtual method.

The reason it gives a strange linker error when you make this mistake, rather than the compiler helpfully telling you "hey dummy you forgot to define this method" is because each time the compiler compiles 1 cpp file at a time, it has no way of knowing that you aren't going to go ahead and define the virtual method somewhere later. Eventually all the compiling is done and the virtual method wasn't found, but by that time it's too late for the compiler to do anything about it. It's a limitation of C++'s compilation model. By this time it is the linker that is running, the linker discovers the error but linkers were invented for assembly language and C, they don't "speak" C++, so they don't give a C++ error, they give a linker error talking about a detail of the C++ implementation that you normally don't see when things are working right.