Page 1 of 1

Undefined reference to '_ZTVN3hal7ConsoleE' [SOLVED]

Posted: Sun Jun 14, 2020 4:04 am
by tongko
I can't get rid of 'undefined reference to '_ZTVN3hal7ConsoleE' which point to constructor of Console class.
I have a static linked library, in it, I've define an pure virtual class name ITty and place in a file name hal.hpp, Console class inherits ITty and have all the virtual function implemented. Everything is fine until I decide to add a global variable 'Console theConsole'. No matter where I place this global variable within the static library's scope, I'll get the 'undefined reference...' error message.

hal.hpp

Code: Select all

namespace hal {
class ITty {
public:
	// Attributes
	virtual CONSOLE_COLOR GetForeColor()				   = 0;
	virtual void		  SetForeColor(CONSOLE_COLOR fore) = 0;
	virtual CONSOLE_COLOR GetBackColor()				   = 0;
	virtual void		  SetBackColor(CONSOLE_COLOR back) = 0;

public:
	// Operations
	virtual DWORD Print(const char *, ...) = 0;
	virtual void  Clear()				   = 0;
	virtual void  MoveTo(const PCOORD)	   = 0;
	virtual INT	  PutChar(INT)			   = 0;
};
}
Console.hpp

Code: Select all


namespace hal {
class Console : public ITty {
	COORD		  m_pos;
	CONSOLE_COLOR m_back;
	CONSOLE_COLOR m_fore;

public:	   //	Constructor
	Console(CONSOLE_COLOR, CONSOLE_COLOR);
	~Console();

public:
	// Attributes
	CONSOLE_COLOR GetForeColor();
	void		  SetForeColor(CONSOLE_COLOR fore);
	CONSOLE_COLOR GetBackColor();
	void		  SetBackColor(CONSOLE_COLOR back);

public:
	// Operations
	DWORD Print(const char *, ...);
	void  Clear();
	void  MoveTo(const PCOORD);
	INT	  PutChar(INT);

private:
	// Operations
	int PrintBuffer(char *__restrict, const char *__restrict, va_list);
	int PrintNumber(char *, int, format_specifier_t *);
	int PrintString(char *, const char *, format_specifier_t *);
};
}
Console.cpp

Code: Select all

Definition of Console class define here.
hal.cpp

Code: Select all


namespace hal {

Console theConsole(CONSOLE_COLOR::WHITE, CONSOLE_COLOR::BLUE);

//    The rest are all hal code.
...
}
build output

Code: Select all

/home/tongko/opt/cross/x86_64-elf/lib/gcc/x86_64-elf/10.1.0/../../../../x86_64-elf/bin/ld: /home/tongko/projects/qios/obj/libhal.a(Console.o): in function `_ZN3hal7ConsoleC2ENS_13CONSOLE_COLORES1_':
/home/tongko/projects/qios/hal/Console.cpp:340: undefined reference to `_ZTVN3hal7ConsoleE'
/home/tongko/opt/cross/x86_64-elf/lib/gcc/x86_64-elf/10.1.0/../../../../x86_64-elf/bin/ld: /home/tongko/projects/qios/obj/libhal.a(Console.o): in function `_ZN3hal7ConsoleD2Ev':
/home/tongko/projects/qios/hal/Console.cpp:342: undefined reference to `_ZTVN3hal7ConsoleE'
collect2: error: ld returned 1 exit status
line 340 and 342 in Console.cpp are definition of constructor and destructor:

Code: Select all

Console::Console(CONSOLE_COLOR fore, CONSOLE_COLOR back)
	: m_fore(fore)
	, m_back(back) {}

Console::~Console() {
	// Nothing to delete.
}
Before I add a destructor, the error message is pointing to first line of the class declaration. After adding destructor, I've got this. If I remove the global variable, then the build succeeded.

I've run out of idea what to look at, as this is just a very simple class and global variable.

Re: Undefined reference to '_ZTVN3hal7ConsoleE'

Posted: Sun Jun 14, 2020 5:25 am
by Korona
The issue is that the first virtual function is defined nowhere.

Compilers emit the vtable while compiling the first virtual function of a class (to avoid multiple definitions / messing around with COMMON sections).

Re: Undefined reference to '_ZTVN3hal7ConsoleE'

Posted: Sun Jun 14, 2020 6:54 am
by tongko
I didn't know that one need to define the pure virtual function, nevertheless, I've added a file ITty.cpp:

Code: Select all

#include <hal.hpp>
#include <types.hpp>

namespace hal {

CONSOLE_COLOR ITty::GetForeColor() {}

void ITty::SetForeColor(CONSOLE_COLOR fore) {}

CONSOLE_COLOR ITty::GetBackColor() {}

void ITty::SetBackColor(CONSOLE_COLOR back) {}

DWORD ITty::Print(const char *fmt, ...) {}

void ITty::Clear() {}

void ITty::MoveTo(const PCOORD pCoord) {}

INT ITty::PutChar(INT value) {}

}	 // namespace hal
but it make no difference...

Re: Undefined reference to '_ZTVN3hal7ConsoleE'

Posted: Sun Jun 14, 2020 6:59 am
by Korona
Not the pure virtual functions but the overriden ones in the Console class (they are only pure in the base class). By the way, it is good practice to add the override keyword here.

Re: Undefined reference to '_ZTVN3hal7ConsoleE'

Posted: Sun Jun 14, 2020 7:04 am
by tongko
After re-read your post, I think I definitely miss out something about the pure virtual in C++, thus, I check that again and found that if one doesn't provide the destructor body even if it is pure virtual class (interface), then compiler will throw the error I'm hitting now.

Thank you very much for the advise, thought.

P.s. I'll start using the keyword override from now onwards :D

Re: Undefined reference to '_ZTVN3hal7ConsoleE'

Posted: Sun Jun 14, 2020 9:31 am
by tongko
I celebrate too early... :(

After applying changes, now I fall into another 'undefined references to ' error message

Code: Select all

/home/tongko/opt/cross/x86_64-elf/lib/gcc/x86_64-elf/10.1.0/../../../../x86_64-elf/bin/ld: /home/tongko/projects/qios/obj/libhal.a(Console.o): in function `_ZN3hal7ConsoleD0Ev':
/home/tongko/projects/qios/hal/Console.cpp:344: undefined reference to `_ZdlPvm'
In face, I don't have the any symbol named _ZdlPvm or anything close.

Re: Undefined reference to '_ZTVN3hal7ConsoleE'

Posted: Sun Jun 14, 2020 10:26 am
by Octocontrabass
tongko wrote:_ZdlPvm
This thread might help.

Re: Undefined reference to '_ZTVN3hal7ConsoleE'

Posted: Sun Jun 14, 2020 9:22 pm
by tongko
Octocontrabass wrote:
tongko wrote:_ZdlPvm
This thread might help.
Thank you so much! All I need to do is to include my declaration of [new] & [delete] operators, then all is working now.