OmnipotentEntity
OmnipotentEntity

Reputation: 17131

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.

Upvotes: 5

Views: 1386

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726639

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.

Upvotes: 9

Remus Rusanu
Remus Rusanu

Reputation: 294307

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

Upvotes: 10

Related Questions