Why doesn't g++ complain when derived class calls pure virtual function of base?
Asked Answered
C

2

5

I have a class Base with a pure virtual function f(). Another class Derived derives from Base. I call f() from within Derived. And using g++, I get an error from the linker.

[agnel@dooku tmp]$ g++ pure_virtual_function_call.cpp 
/tmp/ccGQLHi4.o: In function `Derived::f()':
pure_virtual_function_call.cpp:(.text._ZN7Derived1fEv[_ZN7Derived1fEv]+0x14): undefined reference to `VirtualBase::f()'
collect2: error: ld returned 1 exit status

It seems to me that the error was caught by the linker. Why didn't the compiler report this error? Why leave it to the linker?

Here is the code:

#include <iostream>

using namespace std;

class VirtualBase {
public:
    virtual void f() = 0;
};

class Derived : public VirtualBase {
public:
    void f(){
        VirtualBase::f();
        cout << "Derived\n" ;
    }
};


int main(){
    Derived d;
    d.f();
    return 0;
}
Carditis answered 27/9, 2012 at 17:12 Comment(2)
Could you please show the source code? That would make it much easier to understand.Coddle
Please show your example code. Without that, it will be difficult to answer.Lopez
H
12

Because pure virtual functions can have definitions and, if they do, you are allowed to call them non-virtually using the syntax VirtualBase::f().

The compiler has no way to tell whether you intend the function to be defined or not, and so the error can only be detected by the linker.

Histogram answered 27/9, 2012 at 17:17 Comment(3)
Example of when a pure virtual can have a definition?Carditis
@AgnelKurian: What do you mean? Any pure virtual function can have a definition.Histogram
I did not know that pure virtual functions can have a definition. Thanks.Carditis
D
8

It's not an error to call a pure virtual function. It's an error to call any function that does not have a definition. A pure virtual function can have a definition.

Dissenter answered 27/9, 2012 at 17:15 Comment(12)
Example of when a pure virtual can have a definition?Carditis
@AgnelKurian any time. class C { virtual void f() = 0; }; void C::f() { }Valrievalry
You should add, that only not virtual call is allowedBract
The way he is calling the function qualified by the class name it doesn't really matter that it's a virtual function because he is calling it directly, bypassing the virtual function mechanism.Coddle
@Bract - no, a virtual call is always allowed. That's the most common usage. A virtual call won't hit the definition of the pure virtual, except sometimes from a constructor or destructor.Dissenter
@SegFault, it is theoretically possible to call pure virtual function in virtual way and it will result in throwing an exceptionBract
@Lol4t0: No, it's not possible to call a pure virtual function virtually. The closest you can get is it to invoke undefined behaviour by trying to call it virtually from the constructor of an abstract class. And your example doesn't thow an exception; it calls terminate, which is how that particular compiler chooses to implement the undefined behaviour.Histogram
@MikeSeymour, but it does make the difference. You can still call it directly from constructor & destructor. (in another implantation it trowed, so I should've remembered it, but it doesn't matter in context of discussion)Bract
@Bract - calling a virtual function virtually (Phew!) from a constructor or a destructor produces undefined behavior. (Despite what I said above; I just looked it up)Dissenter
@Lol4t0: No you can't. You can write code that tries to do that, but it will have undefined behaviour. In the words of the standard, "the effect of making a virtual call to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined. "Histogram
@MikeSeymour, now we only have to get virtual call definition. (see 10.3.15 in this context)Bract
@Lol4t0: No, all we have to do is end this off-topic discussion.Histogram

© 2022 - 2024 — McMap. All rights reserved.