0

I've been searching for a while and have found a lot of threads/pages that involve the problem I have, but I am not able to find

  1. An explanation of why this error occurs
  2. A working solution for my specific case

The following is Scanner.h:

class BaseReader {

    public:

    virtual ~BaseReader();

    virtual const char* read() = 0;
    virtual long position() = 0;
    virtual long size() = 0;
    virtual void seek(long position) = 0;

};

class CharReader : public BaseReader {

    public:

    CharReader(const char* source);
    CharReader(const char* source, long size);

    ~CharReader();

    const char* read();
    long position();
    long size();
    void seek(long position);

    private:

    char* _source;
    long _position;
    long _size;

};

In Scanner.cpp I simply implement one of the constructors of CharReader.

I use Code::Blocks, but compiling it by myself results in the exact same problem.

niklas@emerald:~/git/hiterator (CPP)$ g++ main.cpp hiterator/Scanner.cpp -o main
/tmp/cclNNwgl.o: In function `hiterator::CharReader::CharReader(char const*)':
Scanner.cpp:(.text+0x16): undefined reference to `vtable for hiterator::CharReader'
collect2: ld gab 1 als Ende-Status zurück

@qdii:

#include "Scanner.h"
using namespace hiterator;

#include <stdlib.h>
#include <string.h>

CharReader::CharReader(const char* source) {
    _size = strlen(source);
    _source = (char*) malloc(_size + 1);
    memcpy(_source, source, _size + 1);
}
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
Niklas R
  • 16,299
  • 28
  • 108
  • 203
  • can you paste the .cpp as well ? very probably a missing definition of one of the virtual base function. – qdii Jun 12 '12 at 14:54
  • 1
    well all pure virtual functions should have a definition, most of them do not :) – qdii Jun 12 '12 at 15:06

3 Answers3

3

Your program is incorrect. All virtual functions are considered used (odr-used) and thus you need to provide the definitions for all of them. Once you fix that, the issue should go away.

The compiler is complaining that the vtable is not available. Vtable-s are an implementation detail, and thus not treated by the standard, but many compilers will generate the vtable in the translation unit that defines the first (non-inline) virtual function. In your case, whatever the criterion to generate the vtable is, you are not complying with it.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • Indeed, that's it. :o After implementing all methods in `CharReader` the compilation works fine. Thanks! – Niklas R Jun 12 '12 at 15:05
3

See what I wrote on the GCC wiki to explain undefined reference to vtable for X errors.

There are also loads of existing questions on SO about that linker error, I'm sure one of them has an answer that explains it, e.g. here or here

Community
  • 1
  • 1
Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
3

You declared, but didn’t define, the virtual destructor in BaseReader. You need to provide a definition for this in the .cpp file in order for the vtable for BaseReader to be generated. Same for CharReader.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Adding `BaseReader::~BaseReader() { }` to the *.cpp* file doesn't fix the problem. – Niklas R Jun 12 '12 at 15:01
  • @NiklasR Ah, *and* for `CharReader`. The vtable is generated for each class separately, of course. – Konrad Rudolph Jun 12 '12 at 15:09
  • Then it says `undefined reference to read()` (for all methods). But it fixed the `vtable` thing and the rest is easy. :) +1 – Niklas R Jun 12 '12 at 15:12
  • 1
    @NiklasR That’s true, but this error message should be self-explanatory. ;-) And in fact, it only says that if you actually *do* refer to the function. – Konrad Rudolph Jun 12 '12 at 15:37