g++ linker error--typeinfo, but not vtable
- by James
I know the standard answer for a linker error about missing typeinfo usually also involves vtable and some virtual function that I forgot to actually define.
I'm fairly certain that's not the situation this time.
Here's the error:
UI.o: In function boost::shared_ptr<Graphics::Widgets::WidgetSet>::shared_ptr<Graphics::Resource::GroupByState>(boost::shared_ptr<Graphics::Resource::GroupByState> const&, boost::detail::dynamic_cast_tag)':
UI.cpp:(.text._ZN5boost10shared_ptrIN8Graphics7Widgets9WidgetSetEEC1INS1_8Resource12GroupByStateEEERKNS0_IT_EENS_6detail16dynamic_cast_tagE[boost::shared_ptr<Graphics::Widgets::WidgetSet>::shared_ptr<Graphics::Resource::GroupByState>(boost::shared_ptr<Graphics::Resource::GroupByState> const&, boost::detail::dynamic_cast_tag)]+0x30): undefined reference totypeinfo for Graphics::Widgets::WidgetSet'
Running c++filt on the obnoxious mangled name shows that it actually is looking at .boost::shared_ptr::shared_ptr(boost::shared_ptr const&, boost::detail::dynamic_cast_tag)
The inheritance hierarchy looks something like
class AbstractGroup
{
typedef boost::shared_ptr<AbstractGroup> Ptr;
...
};
class WidgetSet : public AbstractGroup
{
typedef boost::shared_ptr<WidgetSet> Ptr;
...
};
class GroupByState : public AbstractGroup
{
...
};
Then there's this:
class UI : public GroupByState
{
...
void LoadWidgets( GroupByState::Ptr resource );
};
Then the original implementation:
void UI::LoadWidgets( GroupByState::Ptr resource )
{
WidgetSet::Ptr tmp( boost::dynamic_pointer_cast< WidgetSet >(resource) );
if( tmp )
{
...
}
}
Stupid error on my part (trying to cast to a sibling class with a shared parent), even if the error is kind of cryptic.
Changing to this:
void UI::LoadWidgets( AbstractGroup::Ptr resource )
{
WidgetSet::Ptr tmp( boost::dynamic_pointer_cast< WidgetSet >(resource) );
if( tmp )
{
...
}
}
(which I'm fairly sure is what I actually meant to be doing) left me with a very similar error:
UI.o: In function boost::shared_ptr<Graphics::Widgets::WidgetSet>::shared_ptr<Graphics::_Drawer::Group>(boost::shared_ptr<Graphics::_Drawer::Group> const&, boost::detail::dynamic_cast_tag)':
UI.cpp:(.text._ZN5boost10shared_ptrIN8Graphics7Widgets9WidgetSetEEC1INS1_7_Drawer5GroupEEERKNS0_IT_EENS_6detail16dynamic_cast_tagE[boost::shared_ptr<Graphics::Widgets::WidgetSet>::shared_ptr<Graphics::_Drawer::Group>(boost::shared_ptr<Graphics::_Drawer::Group> const&, boost::detail::dynamic_cast_tag)]+0x30): undefined reference totypeinfo for Graphics::Widgets::WidgetSet'
collect2: ld returned 1 exit status
dynamic_cast_tag is just an empty struct in boost/shared_ptr.hpp. It's just a guess that boost might have anything at all to do with the error.
Passing in a WidgetSet::Ptr totally eliminates the need for a cast, and it builds fine (which is why I think there's more going on than the standard answer for this question).
Obviously, I'm trimming away a lot of details that might be important. My next step is to cut it down to the smallest example that fails to build, but I figured I'd try the lazy way out and take a stab on here first.
TIA!