Advertisement

Linker problem!

Started by July 22, 2004 04:08 PM
4 comments, last by DarkNebula 20 years, 3 months ago
I'm having a linker problem g++ version: g++ (GCC) 3.3.2 (Mandrake Linux 10.0 3.3.2-6mdk) Here is the error I'm getting:
./bin/GUImain.o(.gnu.linkonce.t._ZN11gs_MainMenuC1Ev+0x19): In function `gs_MainMenu::gs_MainMenu[in-charge]()':
/home/darknebula/gui/GUImain.cpp:13: undefined reference to `vtable for gs_MainMenu'
collect2: ld returned 1 exit status
make: *** [bin/gui] Error 1

Here is my makefile:

INCLUDE = -I./
LIB = -L/usr/X11R6/lib -lGL -lGLU -lXxf86vm

all: ./bin/gui
	
./bin/OpenGL.o: ./*.cpp ./*.h
	g++ -Wall -ggdb -c -o ./bin/OpenGL.o ./OpenGL.cpp $(INCLUDE)

./bin/GUImain.o: ./*.cpp ./*.h
	g++ -Wall  -ggdb -c -o ./bin/GUImain.o ./GUImain.cpp $(INCLUDE)

./bin/gui: ./bin/OpenGL.o ./bin/GUImain.o
	g++ -Wall -ggdb -o ./bin/gui ./bin/OpenGL.o ./bin/GUImain.o $(LIB)

Here is the code where the error appears and the class:


GUImain.h:
class gs_MainMenu : public c_GameState {
public:
	bool Initialize(GL_Window *Window, 
                 c_Keys *Keys, c_Mouse *Mouse);
    void Deinitialize(void);
    void Update(DWORD milliseconds);
    void Draw(void);
    void Resize(int w, int h);
}; 

OpenGL.h:
class c_GameState {
public:
    virtual bool Initialize(GL_Window *Window, 
                 c_Keys *Keys, c_Mouse *Mouse)=0;
    virtual void Deinitialize(void)=0;
    virtual void Update(DWORD milliseconds)=0;
    virtual void Draw(void)=0;
    virtual void Resize(int w, int h)=0;
    
    void ChangeGameState(c_GameState *cGameState, bool init=true, bool deinit=true);
    
    GL_Window   *window;
    c_Keys      *keys;
    c_Mouse     *mouse; 
};

All I did was this:

bool GL_Window::Init()
{
	gs_MainMenu *gsMm = new gs_MainMenu;
    return true;
} 


Thanks!
When you have a class definition with virtual functions, g++ sticks the virtual function table in the translation unit that defines the first non-pure non-inline virtual function. If that definition is missing, g++ might not generate the vtbl. So you may have something like that in your code.

class Foo{public:  virtual void blah(); // The first virtual function declared but not defined.  virtual ~Foo();};Foo::~Foo() {}  // Defined, but not first.


Edit - viewing your code, I see you have a function body for a GL_Window::Init function, but do you have one for gs_MainMenu::Initialize ? (the first non-inline, non-pure virtual function in c_GameState)

Edit2 - By the way, your base class needs a virtual destructor.

[Edited by - Fruny on July 22, 2004 4:21:19 PM]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Advertisement
Now I have:

class gs_MainMenu : public c_GameState {public:    bool Initialize(GL_Window *Window,                  c_Keys *Keys, c_Mouse *Mouse);    void Deinitialize(void);    void Update(DWORD milliseconds);    void Draw(void);    void Resize(int w, int h);	   ~gs_MainMenu();};gs_MainMenu::~gs_MainMenu() {}


Here is my entire GUImain.cpp file:

bool Initialize(GL_Window *Window,                  c_Keys *Keys, c_Mouse *Mouse){	return true;}void Deinitialize(void){}void Update(DWORD milliseconds){}void Draw(void){}void Resize(int w, int h){}bool GL_Window::Init(){    gs_MainMenu *gsMm = new gs_MainMenu;    gsMm->ChangeGameState(gsMm);    return true;}  


and now I have these errors:

./bin/GUImain.o(.text+0xb): In function `gs_MainMenu::~gs_MainMenu [not-in-charge]()':/home/darknebula/gui/GUImain.h:17: undefined reference to `vtable for gs_MainMenu'./bin/GUImain.o(.text+0x16): In function `gs_MainMenu::~gs_MainMenu [not-in-charge]()':/home/darknebula/gui/GUImain.cpp:19: undefined reference to `c_GameState::~c_GameState [not-in-charge]()'./bin/GUImain.o(.text+0x45): In function `gs_MainMenu::~gs_MainMenu [in-charge]()':/home/darknebula/gui/GUImain.h:17: undefined reference to `vtable for gs_MainMenu'./bin/GUImain.o(.text+0x50):/home/darknebula/gui/GUImain.h:17: undefined reference to `c_GameState::~c_GameState [not-in-charge]()'./bin/GUImain.o(.text+0x7f): In function `gs_MainMenu::~gs_MainMenu [in-charge deleting]()':/home/darknebula/gui/GUImain.h:17: undefined reference to `vtable for gs_MainMenu'./bin/GUImain.o(.text+0x8a):/home/darknebula/gui/GUImain.h:17: undefined reference to `c_GameState::~c_GameState [not-in-charge]()'./bin/GUImain.o(.gnu.linkonce.t._ZN11gs_MainMenuC1Ev+0x19): In function `gs_MainMenu::gs_MainMenu[in-charge]()':/home/darknebula/gui/GUImain.cpp:19: undefined reference to `vtable for gs_MainMenu'./bin/GUImain.o(.gnu.linkonce.t._ZN11c_GameStateC2Ev+0x8): In function `c_GameState::c_GameState[not-in-charge]()':/home/darknebula/gui/GUImain.h:17: undefined reference to `vtable for c_GameState'collect2: ld returned 1 exit status


Thanks! (I'm sure I've already did something wrong)
Looks like you're missing the gs_MainMenu::'s from most of your methods in GUImain.h.
Quote:
bool Initialize(GL_Window *Window,                  c_Keys *Keys, c_Mouse *Mouse){	return true;}


That's a definition for a non-member function, not for gs_MainMenu::Initialize.

bool gs_MainMenu::Initialize(GL_Window *Window,                  c_Keys *Keys, c_Mouse *Mouse){	return true;}


idem for the others.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Oh my god. I can't believe I did that. I'm so off today :( Thanks guys! I feel so stupid... lol

This topic is closed to new replies.

Advertisement