Bug 42540

Summary: c++ error message [vtable undefined] is unhelpful
Product: gcc Reporter: Debian GCC Maintainers <debian-gcc>
Component: otherAssignee: Jeffrey Yasskin <jyasskin>
Status: ASSIGNED ---    
Severity: enhancement CC: eyalroz, gcc-bugs, jyasskin, jyasskin, lichray, manu, phresnel
Priority: P3 Keywords: diagnostic
Version: 4.5.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2010-07-13 22:58:26
Bug Depends on:    
Bug Blocks: 46542    

Description Debian GCC Maintainers 2009-12-29 14:44:24 UTC
class A {
    A();

    virtual void B();
};

A::A() {}
/* Whoops, I forgot to define A::B() */

$ g++ -Wall a.cc 
/usr/lib/../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/tmp/ccaVlePI.o: In function `A::A()':
a.cc:(.text+0xf): undefined reference to `vtable for A'
collect2: ld returned 1 exit status

bug submitter writes:
"To be clear: the problem is that the error message only mentions the constructor, and the vtable. It doesn't mention the method A::B(), which is actually the problem. On a less-minimal example it could take much longer to work out what the real problem is."
Comment 1 Andrew Pinski 2009-12-29 15:05:46 UTC
I don't know if there is anything there could be done here since the linker is what is producing the error.
Comment 2 Andrew Pinski 2009-12-29 19:26:52 UTC
In fact it depends on the key function being declared which depends on the ABI really (ARM EABI has a slightly different key function than the rest of the abis).
Comment 3 Jonathan Wakely 2010-01-06 10:42:05 UTC
The linker error alone doesn't make the root cause obvious, but it's a fairly well known and well documented problem:
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.10
Comment 4 Manuel López-Ibáñez 2010-02-24 13:25:46 UTC
Is it impossible to detect this in the compiler?

Can't we put the vtable somewhere else (or break it in pieces) such triggering the error in the compiler?

Otherwise, we should just close this as WONTFIX.
Comment 5 Richard Earnshaw 2010-02-24 14:17:28 UTC
As suggested, there's no bug in the compiler here, and the error message comes from the linker.  The linker doesn't know what the key function is, so I doubt it could issue a more accurate diagnostic.

In fact, the key function is just a trigger to the compiler to cause it to emit the meta-data for the class exactly once -- and because there the class could be used in multiple compilation units it can never know which one should contain the meta data as any of them could have done.  As far as the linker is concerned, there really is no class for A; it's the same as if there was no definition for a global extern variable.
Comment 6 Andrew Pinski 2010-07-06 15:47:39 UTC
*** Bug 44841 has been marked as a duplicate of this bug. ***
Comment 7 Jeffrey Yasskin 2010-07-13 22:56:43 UTC
I'm working on a patch for this at http://gcc.gnu.org/ml/gcc-patches/2010-07/msg01116.html. It works by emitting a fake use of the key method any time a translation unit depends on an imported vtable or typeinfo.
Comment 8 Andrew Pinski 2010-07-13 22:58:07 UTC
Reopening ....
Comment 9 Manuel López-Ibáñez 2011-03-17 15:39:00 UTC
Pending for 4.7
Comment 10 Jeffrey Yasskin 2011-03-17 16:16:50 UTC
Mark asked for a different implementation in http://gcc.gnu.org/ml/gcc-patches/2010-08/msg00367.html, and I may not get a chance to do what he asked for 4.7. Someone else is welcome to pick this up if they have time.
Comment 11 Zhihao Yuan 2020-02-23 02:56:46 UTC
The example in this bug is not as severe and frequent as the one in bug 44841.  Users are more likely to encounter this issue when adding a new API to existing interface or type erasure.

Calling this a "well-known issue" is irresponsible.  The issue significantly increases the bar to learners to consume and accept new paradigms in the language.

The issue has not been fixed for ten years.  It is a shame rather than some arcane knowledge that worth to be proud of.

MSVC has no such issue.  The error message reads as "undefined reference to Class::that_virtual_function."

Some possible fixes:

1. Adjust the error message to say, "The first non-inline, non-pure function may not have a definition in <Class>."
2. Add extra information to name the key function, and pass it to the linker, generate an error message to match MSVC's quality.
Comment 12 Jonathan Wakely 2020-07-22 13:56:23 UTC
(In reply to Zhihao Yuan from comment #11)
> 1. Adjust the error message to say, "The first non-inline, non-pure function
> may not have a definition in <Class>."

That error comes from the linker. The linker is not part of GCC, so this is the wrong place to ask for linker changes.

> 2. Add extra information to name the key function, and pass it to the
> linker, generate an error message to match MSVC's quality.

That's what comment 7 suggested. Comment 10 links to the response to that.
Comment 13 Jonathan Wakely 2020-07-22 13:57:11 UTC
(In reply to Jonathan Wakely from comment #3)
> The linker error alone doesn't make the root cause obvious, but it's a
> fairly well known and well documented problem:
> http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.10

A better link is now:
https://gcc.gnu.org/wiki/VerboseDiagnostics#undefined_reference_to_vtable_for_X
Comment 14 Jonathan Wakely 2020-07-22 13:57:35 UTC
*** Bug 96283 has been marked as a duplicate of this bug. ***