5

I find it quite odd that unused virtual functions must still be defined unlike unused ordinary functions. I understand somewhat about the implicit vtables and vpointers which are created when a class object is created - this somewhat answers the question (that the function must be defined so that the pointers to the virtual function can be defined) but this pushes my query back further still.

Why would a vtable entry need to be created for a function if there's absolutely no chance that virtual function will be called at all?

class A{
    virtual bool test() const;
};

int main(){
    A a; //error: undefined reference to 'vtable for A'
}

Even though I declared A::test() it was never used in the program but it still throws up an error. Can the compiler not run through the program and realise test() was never called - and thus not require a vtable entry for it? Or is that an unreasonable thing to expect of the compiler?

Ziezi
  • 6,375
  • 3
  • 39
  • 49
AntiElephant
  • 1,227
  • 10
  • 18
  • You can't instantiate a virtual class. But it is trivial to create a null function or one that simply returns a constant of its declared type. – Logicrat Oct 09 '15 at 20:40

3 Answers3

6

Because it would inevitably be a very difficult problem to solve on the compiler writer's part, when the usefulness of being able to leave virtual functions undefined is at best dubious. Compiler authors surely have better problems to solve.

Besides, you ARE using that function even though you don't call it. You are taking its address.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • I would even say that it's impossible to solve: Say you have a library that you open with `dlopen` that gives you a pointer to a class that has an undefined virtual function. It's not possible for the compiler to catch this, so this would be a runtime error... – znkr Oct 09 '15 at 22:33
3

The OP says that he already knows about vtables and vpointers, so he understands that there is a difference between unused virtual functions and unused non-virtual functions: an unused non-virtual function is not referenced anywhere, while a virtual function is referenced at least once, in the vtable of its class. So, essentially the question is asking why is the compiler not smart enough to refrain from placing a reference to a virtual function in the vtable if that function is not used anywhere. That would allow the function to also go undefined.

The compiler generally sees only one .cpp file at a time, so it does not know whether you have some source file somewhere which invokes that function.

Some tools support this kind of analysis, they call it "global" analysis or something similar. You might even find it built-in in some compilers, and accessible via some compiler option. But it is never enabled by default, because it would tremendously slow down compilation.

As a matter of fact, the reason why you can leave a non-virtual function undefined is also related to lack of global analysis, but in a different way: if the compiler knew that you have omitted the definition of a function, it would probably at least warn you. But since it does not do global analysis, it can't. This is evidenced by the fact that if you do try to use an undefined function, the error will not be caught by the compiler: it will be caught by the linker.

So, just define an empty virtual function which contains an ASSERT(FALSE) and proceed with your life.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • @AlexD well, the OP says that he already knows about vtables and vpointers, so I did not feel that I needed to address this. But you are right, it is best to state things than to leave things implied. So, I amended my answer. – Mike Nakis Oct 10 '15 at 07:01
  • "The compiler generally sees only one .cpp file at a time, so it does not know whether you have some source file somewhere which invokes that function." If I had a source file which invoked that function, wouldn't that source file have a header included for that class - which lacks the virtual definition - anyway? How would I invoke a member function without having defined the class in the source file? – AntiElephant Oct 10 '15 at 12:57
  • @AntiElephant there is a [difference between declaration and definition](http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration). the header file will contain the ***declaration*** of the function, making it legal for any piece of code to place a call to that function. But the ***definition*** of the function is where you provide the actual function body, and this is usually done in one .cpp file. – Mike Nakis Oct 10 '15 at 13:41
  • Sorry, by "invoke" the function did you mean define it? – AntiElephant Oct 10 '15 at 14:12
  • @AntiElephant no, by "invoke" I mean what "invoke" normally means, which is "call". – Mike Nakis Oct 10 '15 at 19:04
  • @AntiElephant if the compiler could see that you never invoke the function from any .cpp file, then it could in theory omit generating its vtable entry, in which case it would not be an error to leave that function also undefined. – Mike Nakis Oct 10 '15 at 19:05
0

The whole point of virtual functions is that they can be called through a base class pointer. If you never use the base class virtual function, then, why did you define it ? If it is used, they you either have to leave the parent implementation (if it's not pure virtual), or define your own implementation, so that code using your objects through the base class can actually make use of it. In that case, the function is used, it's just not used directly.

Vincent Fourmond
  • 3,038
  • 1
  • 22
  • 24