Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is calling a pure virtual a linker error rather than a compile error?

It's a bit surprising to me that this program:

struct A {
  virtual void a()=0;
};

struct B : public A {
  void a() {}
};

int main() {
  B b;
  b.a(); // OK, call B::a()
  b.A::a(); // linker error?
}

Gave me this error (gcc 4.4):

/tmp/ccfOGuBJ.o: In function `main':
test.cc:(.text+0x28): undefined reference to `A::a()'
collect2: ld returned 1 exit status

(clang 7.0.0)

Undefined symbols for architecture x86_64:
  "A::a()", referenced from:
      _main in test-440cc5.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I expected that attempting to call a pure function would give an explicit error, because it was declared as deleted, rather than an implicit error. Is there not a distinction in the standard between "function not in this translation unit," and "function not in any translation unit?"

It should be noted that attempting to directly call a pure virtual is not addressed in §10.4.

like image 248
OmnipotentEntity Avatar asked Sep 22 '15 16:09

OmnipotentEntity


People also ask

Can pure virtual function be called?

A pure virtual function is declared, but not necessarily defined, by a base class. A class with a pure virtual function is "abstract" (as opposed to "concrete"), in that it's not possible to create instances of that class.

Can pure virtual function have implementation?

A pure virtual function (or abstract function) in C++ is a virtual function for which we can have implementation, But we must override that function in the derived class, otherwise the derived class will also become abstract class (For more info about where we provide implementation for such functions refer to this ...

Why we can not create object of such a class which contains pure virtual function in it?

Programmers need to redefine the pure virtual function in the derived class as it has no definition in the base class. A class having pure virtual function cannot be used to create direct objects of its own. It means that the class is containing any pure virtual function then we cannot create the object of that class.

Which one of the following is the correct way to declare a pure virtual?

You declare a pure virtual function by using a pure specifier ( = 0 ) in the declaration of a virtual member function in the class declaration.


2 Answers

Pure virtual functions can have a body. Therefore the error is a link error, because you fail to provide the body.

like image 67
Remus Rusanu Avatar answered Nov 04 '22 23:11

Remus Rusanu


Mark a function pure virtual does not mean that the function will have no implementation. All it means is that classes which derive from yours must either override this specific member function, or remain abstract. In particular, it is perfectly legal to provide an implementation of a pure virtual function for classes that derive from yours to inherit and use.

That is why the presence (or absence) of an implementation cannot be detected until the linking stage: you could provide an implementation in a separate translation unit, so the compiler may not know of it.

like image 29
Sergey Kalinichenko Avatar answered Nov 04 '22 22:11

Sergey Kalinichenko