I'm currently writing a library that has some abstract classes. In addition to checking that the library compiles, I'd like to make sure that all pure virtual methods have been defined in classes that are intended to be concrete. I had hoped that I could get this information from nm
or objdump
, but so far I haven't been able to tell.
Consider the following minimal example:
struct A
{
void f() {}
};
struct B
{
virtual void f() = 0;
};
struct C : public B
{
void f() override {}
};
When I look at the nm
output, I get the following. (I've excluded anything that doesn't relate to one of these classes.)
% nm -C test.so
0000000000001174 W A::f()
000000000000118c W B::B()
000000000000118c W B::B()
0000000000001180 W C::f()
00000000000011aa W C::C()
00000000000011aa W C::C()
0000000000003db0 V typeinfo for B
0000000000003d98 V typeinfo for C
0000000000002003 V typeinfo name for B
0000000000002000 V typeinfo name for C
0000000000003d80 V vtable for B
0000000000003d68 V vtable for C
It's easy to distinguish A
(a class with no virtual methods) from B
and C
. But I want to be able to distinguish the fact that B
is an abstract class whereas C
is concrete.
Obviously, if I have a list of all pure virtual methods, and a map of the class hierarchy, then I could iterate over them and check whether they are defined. (Above, you can see that C::f
is defined, but B::f
is not.) But I was hoping that there would be an automatic way of doing this. (I was hoping that the vtable
or typeinfo
would show up differently above.)
Another way would be to add an extra file where I instantiate one object from every class that I expect to be concrete, and I will get a compiler error if any of them have undefined virtual methods. But this is also annoying.
Clearly, I'm not an expert on ELF or the C object file model in general, so I'd appreciate a useful introduction or reference if the answer turns out to be complicated.