I have a class with a static method that looks roughly like:
class X {
static float getFloat(MyBase& obj) {
return obj.value(); // MyBase::value() is virtual
}
};
I'm calling it with an instance of MyDerived which subclasses MyBase:
MyDerived d;
float f = X::getFloat(d);
If I link the obj file containing X into my executable, everything works as expected. If I'm expecting to get 3.14, I get it.
If I create a .lib that contains the X.obj file and link in the .lib, it breaks. When I call getFloat(), it's returning -1.#IND00. Is this some type of sentinel value that should tell me what's wrong here?
Is anything different when you link in a lib rather than an obj directly?
I don't get any compiler warnings or errors.
Edit:
I'm using Visual Studio 2005 on Windows XP Pro SP3. To make sure I wasn't linking old files, I cloned the value() method into a new value2() method and called that instead. The behavior was the same.
Edit #2:
So, if I trace into the call with my debugger, I'm finding that it isn't going into my value() method at all. Instead it's going into a different (unrelated) method. This makes me think my vtable is corrupted. I think the behavior I'm seeing must be a side effect of some other problem.
Solved! (thanks to Vlad)
It turns out I was violating the one definition rule (ODR) although it wasn't evident from the code I posted. This is a great article from the Visual C++ guys that explains the problem and one way to track it down. The /d1reportSingleClassLayout compiler flag is a fantastic learning tool.
When I dumped out the my class layout for MyBase and MyDerived in the two different projects, I found differences between the calling code and the library code. It turns out I had some #ifdef blocks in my header files and the corresponding #define statement was in the precompiled header for the main project but not in the subproject (the library). Have I mentioned how evil I think preprocessor macros are?
Anyway, I'm only posting this stuff because it might be helpful to somebody else. This question was also very helpful to me.