SOLVED: compiler error: ''Undefined symbols: typeinfo for'' [gcc 4, OS X, Xcode]

Started by
7 comments, last by Zahlman 16 years, 1 month ago
Hi, I'm getting this error:

/usr/bin/ld: Undefined symbols:
typeinfo for physics_object
vtable for physics_object
/Users/speciesunknown/Projects/newton_collision/current_copy/OSX/build/game_engine.build/Release/game_engine.build/Objects-normal/ppc/physics_cube.o reference to undefined typeinfo for physics_object
/Users/speciesunknown/Projects/newton_collision/current_copy/OSX/build/game_engine.build/Release/game_engine.build/Objects-normal/ppc/physics_cube.o reference to undefined vtable for physics_object
collect2: ld returned 1 exit status





what does "typeinfo for physics_object" mean? likewise "vtable for..." Here is the header file for the base class physics_object:

/*
 *  physics_object.h
 */

class physics_object;

#include "physics_cube.h"
#ifndef class_physics_object_h
#define class_physics_object_h 1
#include "renderer.h"
#include "Newton.h"

class physics_object{
private:
protected:
	NewtonWorld* nWorld;
	NewtonBody* phyBody;
public:
	physics_object(){};
	virtual ~physics_object(){};

 	virtual void draw(renderer * r);

	void set_matrix(float m[16]);
	void get_matrix(float *m[16]);
};

#endif





I can't see that its missing anything. here is the (currently only) subclass:

/*
 *  physics_cube.h
 */

class physics_cube;

#ifndef class_physics_cube_h
#define class_physics_cube_h 1
#include "physics_object.h"
#include "g_maths.h"
#include "Newton.h"
#include "dMatrix.h"
#include "renderer.h"
class physics_cube: public physics_object
{
private:
	float width,height,depth;

public:
	physics_cube::physics_cube(float W, float H, float D, float X, float Y, float Z, NewtonWorld * w);
	~physics_cube(){};
	void draw(renderer * r);
	//draw cube in current position
};
#endif






The compiler isn't giving me a line number, so its a linker error. But I;ve never seen it before, nor can I see anything wrong with my code. Thanks for any help. [Edited by - speciesUnknown on February 21, 2008 8:56:06 PM]
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
Advertisement
Did you implement physics_object::draw?
Quote:Original post by Sneftel
Did you implement physics_object::draw?


Thanks for your reply,

yes, here it is:

void physics_cube::draw(renderer * r){	dMatrix position;	NewtonBodyGetMatrix(phyBody, &position[0][0]);		int mindex = 0;	GLfloat m[16];		for(int x=0; x<4; x++)	for(int y=0; y<4; y++){		m[mindex++] = position[x][y];	}	glPushMatrix();		glMultMatrix(m);		renderSolidBox(1,1,1);	glPopMatrix();}


in file physics_cube.cpp, which includes physics_cube.h.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
You might try making physics_object::draw() pure virtual.

Couple of other notes:

1. You don't need the semicolons after the closing brackets of your function definitions.

2. As far as I know, there's no need to define your header guard macros 'as' anything; you can just write '#define some_header_h'.

3. Just out of curiosity, why are you including physics_cube.h in physics_object.h?

4. Are you sure that this is right:
void get_matrix(float *m[16]);
?

Here m represents an array of 16 pointers to objects of type float - is that what you want?
Quote:Original post by jyk
You might try making physics_object::draw() pure virtual.

Couple of other notes:

1. You don't need the semicolons after the closing brackets of your function definitions.

this is a stylistic thing that a couple of people already told me off for. I guess ill change my habits.
Quote:
2. As far as I know, there's no need to define your header guard macros 'as' anything; you can just write '#define some_header_h'.


hmm, thats just a habit. I started off believing that the define would contain junk data so I set it to 1. Am I wrong on this belief?
Quote:

3. Just out of curiosity, why are you including physics_cube.h in physics_object.h?


this is only my second use of inheritance, and I don't know of another way to get it working. The first time I did this I got strange "multiple definitions" errors, so I included the headers of the subclasses in the header of teh superclass, and it started to work.
Quote:

4. Are you sure that this is right:
void get_matrix(float *m[16]);
?

Here m represents an array of 16 pointers to objects of type float - is that what you want?


No, I wanted a pointer to an array of 16 floats.[embarrassed] I'll dereference instead.

Thanks guys, I got it working by stubbing out physics_object::draw(). I thought the subclass version of that function would be enough, and was thrown off by the fact that the error says nothing about the function draw(). reading Sneftels post more closely led me to figuring this out.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
OK, you guys have just helped me remove the last obstacle to getting my multiple bouncing boxes physics demo working. ratings++ (but it didn't make any difference...)

If not for GDnet, I'd still be in the stone age.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
Glad you got it working :)
Quote:Original post by speciesUnknown
Quote:1. You don't need the semicolons after the closing brackets of your function definitions.

this is a stylistic thing that a couple of people already told me off for. I guess ill change my habits.
Yeah, while some 'style' issues really are subjective, this one's pretty cut and dry.. It's basically equivalent to ending every sentence with two periods, which most would consider to be simply incorrect, rather than being a stylistic choice..
Quote:
Quote:2. As far as I know, there's no need to define your header guard macros 'as' anything; you can just write '#define some_header_h'.
hmm, thats just a habit. I started off believing that the define would contain junk data so I set it to 1. Am I wrong on this belief?
Maybe someone else can confirm exactly how the preprocessor works in this respect, but I think if you leave a #define 'empty', then it's just 'empty'. It's defined, but if you were to actually try to use it somewhere, the preprocessor would just replace it with nothing. (In other words, #define's are just text substitution; they're not like variables, and don't really have a 'value' that will be undefined it they're not 'initialized'.)
Quote:
Quote:3. Just out of curiosity, why are you including physics_cube.h in physics_object.h?
this is only my second use of inheritance, and I don't know of another way to get it working. The first time I did this I got strange "multiple definitions" errors, so I included the headers of the subclasses in the header of teh superclass, and it started to work.
I'm not sure what problems you were running into you, but you shouldn't have to do this (in general, you should also avoid placing code outside of the include guards). If I were you, I'd get those extra includes out of there and then just fix whatever problems come up (with help from your fellow GDNet'ers if necessary :).
Quote:Original post by speciesUnknown
Thanks guys, I got it working by stubbing out physics_object::draw(). I thought the subclass version of that function would be enough, and was thrown off by the fact that the error says nothing about the function draw(). reading Sneftels post more closely led me to figuring this out.

The reason this is happening has two parts.

The first part is, the vtable is the only thing that cares about physics_object::draw. You never call that function statically, but the vtable wants a reference to it because it might be invoked in a dynamic binding context (i.e. as a virtual function call). So the compiler will complain about missing draw() when it tries to emit the vtable, right?

The second part is, the compiler needs to put the vtable somewhere. As in, in some translation unit. For functions, that's easy; it just puts them where they're defined. But the vtable technically isn't defined there. One convention that compilers use is to put the vtable in the same translation unit as the first virtual function whose definition is not inline in the class definition. In your case, that's the draw function itself. But since there actually is no translation unit where physics_object::draw is defined, that never actually happens. So the vtable (and the typeinfo) isn't ever emitted, causing the error.

[Edited by - Sneftel on February 22, 2008 9:33:12 AM]
Quote:Original post by speciesUnknown
No, I wanted a pointer to an array of 16 floats.[embarrassed]


Why? The array already decays to a pointer when passed to the function. If you just pass an array, changes to the array contents will be "seen by" the caller. (This is for backwards compatibility with C, where it was seen as a useful convenience).

If you don't want that behaviour, you can wrap the array in a struct, or use the pre-existing wrapper: boost::array. (If you want all the "this is a real object that I can think about just like everything else" convenience of boost::array but you do want to change the array contents and have the caller see it, then you handle that just like you would with any other object: by passing it by non-const reference.)

Quote:and was thrown off by the fact that the error says nothing about the function draw().


Relevant reading. Because IMX it quite often helps to see the same thing written a few different ways. :)

This topic is closed to new replies.

Advertisement