Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

G++ compiler being weird.

Started by Maverick Programmer Jan 1, 2011 at 1:27 PM 27 replies 8k views
Original Post
Maverick Programmer
Maverick Programmer
I have a parent class called Entity and another class named CrawlerTurret which derives from the parent class Entity. When I go to compile and get the object file of the files, however, g++ informs me that there is a member function in there that is not of class Entity. Here's some code and what I'm typing in:

CrawlerTurret.h - FULL
#ifndef CRAWLERTURRET_H#define CRAWLERTURRET_H#include "Particle.h"#include "Map.h"#include "Entity.h"#include "Math.h"class CrawlerTurret : public Entity{public:	enum facing_enum {NONE, LEFT, RIGHT, UP, DOWN};		CrawlerTurret						();	CrawlerTurret						(int x, int y, int w, int h, INPUT_DEVICE = AUTONOMOUS);	static void push			(int x, int y, int w, int h, INPUT_DEVICE input = AUTONOMOUS);	void update					();	void render					(BITMAP* buffer, int mapxoff = 0, int mapyoff = 0);	void crawlerAI                   ();	private:	Entity* target;	facing_enum facing;	facing_enum lastContact;	int lastx, lasty;	int bufferedVelx, bufferedVely;};#endif


CrawlerTurret - SNIPPET
void CrawlerTurret::update(){		Entity::collision_correction(true); // <- This is causing problamos		Entity::update();	int px = 5.0f + fabs(vx);	int py = 5.0f + fabs(vy);	int d = 0; //shooting distance as not to collide with shooting entity	int pw = 5; //particle width	int ph = 5; //particle height	...


Entity.h - FULL
#ifndef _ENTITY_#define _ENTITY_#include <list>#include "Animation.h"#include <stdio.h>#include <math.h>#include "Math.h"using namespace std;//entity state will dictate parameters for how an entity should //react, animate and moveenum ENTITY_STATE{	IDLE = 0,	MOVING,	DEAD,};enum INPUT_DEVICE{	AUTONOMOUS = 0,	KEYBOARD,	JOY0,	JOY1,	JOY2,	JOY3};enum AFFILIATION{	NEUTRAL = 0,	FRIENDLY,	ENEMY};class Entity{public:	Entity					();	Entity					(int col_x, int col_y, int col_w, int col_h);	public://temporarily public for debug printing	static list<Entity*>	entity_list;	int x, y, w, h;			//entity source x,y,w,h		int bx, by, bw, bh;     //bitmap source x,y,w,h        float vx, vy;				//velocity x,y    float ax, ay;				//acceleration x,y	int life;				//if (life < 1) entity = dead; delete;	int damage;				//b.life -= a.damage when colliding	ENTITY_STATE state;	INPUT_DEVICE input;		//AI or keyboard/joystick controlled	AFFILIATION affiliation;	Animation idle;			//the run animation	Animation moving;		//other example animations	Animation dead;	bool inside					(int x,int y,int left,int top,int right,int bottom);		bool use_collision_correction;	bool colliding;public:	static void push					(int x, int y, int w, int h);	static void delete_dead_entities	();	virtual void update					();	virtual void render					(BITMAP* buffer, int mapxoff = 0, int mapyoff = 0);	void load_animation					(ENTITY_STATE animation, char* path, int frames);	Animation *get_animation			(ENTITY_STATE);		bool detect_collision				(Entity* b);	static Entity* get_entity			(int number);	static int get_count				();	void apply_force					(float x = 0, float y = 0);	void move_to						(int x = 0, int y = 0);	void move							();	void collision_correction           (bool on_off = true);	int get_x							();	int get_y							();	int get_w							();	int get_h							();	float get_vx							();	float get_vy							();	void set_life						(int life);	int get_life						();	int get_damage						();	int get_affiliation				();		//level collision routines	int collided_tl(int x, int y);	int get_user_data(int x, int y, int u);};#endif // _ENTITY_


Entity.cpp - SNIPPET
... void Entity::collision_correction(bool on_off){	use_collision_correction = on_off;}...


In Terminal:
g++ -c Entity.cpp Entity.hg++ -c CrawlerTurret.cpp CrawlerTurret.h-- Error in CrawlerTurret.cpp in update function: collision_correction is not a member of Entity



... But update and everything else in there is fine??
Holy crap, you can read!
PMM2103
PMM2103
It has been a while since I've written C++, so please forgive any errors. Some possible problem is that you are trying to call Entity::collision_correction() as a static method. I don't know if it is supposed to be an instance method. If so, you could use the 'this' pointer.
Maverick Programmer
Maverick Programmer
Right, but other things like Entity::update() work fine.

And I sent the exact code to another coder and it compiles fine with Dev-C++.
I'm trying to get experience by staying away from IDEs.

EDIT:
And this-> doesn't work.
Holy crap, you can read!
SiCrane
SiCrane
Well first check to make sure that your version of g++ is up to date. If that doesn't help then make a copy of your project and start deleting stuff until you can identify exactly whats making things go screwy or get down to a minimal compilable code sample that you can post here.
MENTAL
MENTAL
Try without the Entity:: part. Unless you have overrrided/hidden the function, there is usually no need to qualify a call to a base member function with the name of said base class.

Entity::update has no problems as CrawlerTurret hides the Entity::update function, so by calling Entity::update the compiler knows which version you are trying to call.

As was said above, looks like GCC is trying to find a static function called collision_correction. Weird bug, might want to report it as I'm not sure if it's proper C++ behaviour (assuming you can replicate it with test code).
Maverick Programmer
Maverick Programmer
Hrmm. Well, I removed the Entity:: part and got a new error.

CrawlerTurret.cpp:41: error: ‘collision_correction’ was not declared in this scope


So instead of it not being a member, it's not in the scope.
Holy crap, you can read!
Bregma
Bregma
Quote:
Original post by Maverick Programmer
So no real advice then?

My advice is suspect dark preprocessor magic.

Try recompiling with the -save-temps command line switch and check the resulting .i file (the preprocessed file) to make sure everything is as you think it is.
Stephen M. Webb
Professional Free Software Developer
alvaro
alvaro
Perhaps unrelated, but you are not allowed to use the macro name _ENTITY_, because it's reserved to the implementation. Does anyone have a link to the relevant part of the standard handy?
Bregma
Bregma
Quote:
Original post by alvaro
Perhaps unrelated, but you are not allowed to use the macro name _ENTITY_, because it's reserved to the implementation. Does anyone have a link to the relevant part of the standard handy?


I have it as [17.6.3.3.2](1) Global names, quotes as follows.
Quote:

[global.names]

Certain sets of names and function signatures are always reserved to the implementation:

— Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.

— Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.


If you use an include guard like _ENTITY_ you are courting trouble. Check the generated .ii file or try changing the include guard to INCLUDE_ENTITY_H_ (or something) and see if the problem resolves.
Stephen M. Webb
Professional Free Software Developer
Maverick Programmer
Maverick Programmer
I followed Bregma's advice and turned up something interesting. By renaming the #define _ENTITY_ and naming it INCLUDE_ENTITY_H this happens:

First. Entity.cpp and Entity.h compile fine. BUT- when I compile a file that DERIVES from the Entity class- THIS happens:

Maverick$ g++ -c Entity.cpp Entity.h //Side note. This compiles fineMaverick$ g++ -c Fighter.cpp Fighter.h //Side note. This is an empty class that derives from EntityEntity.h:14: error: multiple definition of ‘enum ENTITY_STATE’Entity.h:13: error: previous definition hereEntity.h:14: error: conflicting declaration ‘IDLE’Entity.h:14: error: ‘IDLE’ has a previous declaration as ‘ENTITY_STATE IDLE’Entity.h:14: error: conflicting declaration ‘MOVING’Entity.h:15: error: ‘MOVING’ has a previous declaration as ‘ENTITY_STATE MOVING’Entity.h:14: error: conflicting declaration ‘DEAD’Entity.h:16: error: ‘DEAD’ has a previous declaration as ‘ENTITY_STATE DEAD’Entity.h:16: error: multiple definition of ‘enum INPUT_DEVICE’Entity.h:18: error: previous definition hereEntity.h:16: error: conflicting declaration ‘AUTONOMOUS’Entity.h:19: error: ‘AUTONOMOUS’ has a previous declaration as ‘INPUT_DEVICE AUTONOMOUS’Entity.h:16: error: conflicting declaration ‘KEYBOARD’Entity.h:20: error: ‘KEYBOARD’ has a previous declaration as ‘INPUT_DEVICE KEYBOARD’Entity.h:16: error: conflicting declaration ‘JOY0’Entity.h:21: error: ‘JOY0’ has a previous declaration as ‘INPUT_DEVICE JOY0’Entity.h:16: error: conflicting declaration ‘JOY1’Entity.h:22: error: ‘JOY1’ has a previous declaration as ‘INPUT_DEVICE JOY1’Entity.h:16: error: conflicting declaration ‘JOY2’Entity.h:23: error: ‘JOY2’ has a previous declaration as ‘INPUT_DEVICE JOY2’Entity.h:16: error: conflicting declaration ‘JOY3’Entity.h:24: error: ‘JOY3’ has a previous declaration as ‘INPUT_DEVICE JOY3’Entity.h:18: error: multiple definition of ‘enum AFFILIATION’Entity.h:26: error: previous definition hereEntity.h:18: error: conflicting declaration ‘NEUTRAL’Entity.h:27: error: ‘NEUTRAL’ has a previous declaration as ‘AFFILIATION NEUTRAL’Entity.h:18: error: conflicting declaration ‘FRIENDLY’Entity.h:28: error: ‘FRIENDLY’ has a previous declaration as ‘AFFILIATION FRIENDLY’Entity.h:18: error: conflicting declaration ‘ENEMY’Entity.h:29: error: ‘ENEMY’ has a previous declaration as ‘AFFILIATION ENEMY’Entity.h:20: error: redefinition of ‘class Entity’Entity.h:32: error: previous definition of ‘class Entity’


And just for you who need the Entity.h again and don't want to scroll to the top:

#ifndef INCLUDE_ENTITY_H#define INCLUDE_ENTITY_H#include <list>#include "Animation.h"#include <stdio.h>#include <math.h>#include "Math.h"using namespace std;//entity state will dictate parameters for how an entity should //react, animate and moveenum ENTITY_STATE{	IDLE = 0,	MOVING,	DEAD,};enum INPUT_DEVICE{	AUTONOMOUS = 0,	KEYBOARD,	JOY0,	JOY1,	JOY2,	JOY3};enum AFFILIATION{	NEUTRAL = 0,	FRIENDLY,	ENEMY};class Entity{public:	Entity					();	Entity					(int col_x, int col_y, int col_w, int col_h);	public://temporarily public for debug printing	static list<Entity*>	entity_list;	int x, y, w, h;			//entity source x,y,w,h		int bx, by, bw, bh;     //bitmap source x,y,w,h        float vx, vy;				//velocity x,y    float ax, ay;				//acceleration x,y	int life;				//if (life < 1) entity = dead; delete;	int damage;				//b.life -= a.damage when colliding	ENTITY_STATE state;	INPUT_DEVICE input;		//AI or keyboard/joystick controlled	AFFILIATION affiliation;	Animation idle;			//the run animation	Animation moving;		//other example animations	Animation dead;	bool inside					(int x,int y,int left,int top,int right,int bottom);		bool use_collision_correction;	bool colliding;public:	static void push					(int x, int y, int w, int h);	static void delete_dead_entities	();	virtual void update					();	virtual void render					(BITMAP* buffer, int mapxoff = 0, int mapyoff = 0);	void load_animation					(ENTITY_STATE animation, char* path, int frames);	Animation *get_animation			(ENTITY_STATE);		bool detect_collision				(Entity* b);	static Entity* get_entity			(int number);	static int get_count				();	void apply_force					(float x = 0, float y = 0);	void move_to						(int x = 0, int y = 0);	void move							();	void collision_correction           (bool on_off = true);	int get_x							();	int get_y							();	int get_w							();	int get_h							();	float get_vx							();	float get_vy							();	void set_life						(int life);	int get_life						();	int get_damage						();	int get_affiliation				();		//level collision routines	int collided_tl(int x, int y);	int get_user_data(int x, int y, int u);};#endif


No other changes were made.
Holy crap, you can read!
SiCrane
SiCrane
Actually that change makes it sound like you've got two copies of your entity header lying around and one source file or header file is including the one you're currently working on and another source or header file is including the old one.
Bregma
Bregma
Quote:
Original post by Maverick Programmer
I followed Bregma's advice and turned up something interesting.

What SiCrane said. Compile with -save-temps and examine the .ii file. What I tell you three times is true.
Stephen M. Webb
Professional Free Software Developer
Maverick Programmer
Maverick Programmer
Quote:
Original post by Bregma
Quote:
Original post by Maverick Programmer
I followed Bregma's advice and turned up something interesting.

What SiCrane said. Compile with -save-temps and examine the .ii file. What I tell you three times is true.


Mkay.

# 1 "CrawlerTurret.h"# 1 "<built-in>"# 1 "<command line>"# 1 "CrawlerTurret.h"#pragma GCC pch_preprocess "Particle.h.gch"# 1 "Map.h" 1# 1 "Define.h" 1# 5 "Map.h" 2# 1 "Entity.h" 1# 1 "/usr/include/c++/4.0.0/list" 1 3# 5 "Entity.h" 2# 1 "Animation.h" 1# 6 "Entity.h" 2# 1 "/usr/include/stdio.h" 1 3 4# 7 "Entity.h" 2# 1 "/usr/include/math.h" 1 3 4# 8 "Entity.h" 2# 1 "Math.h" 1class Math{public: Math(); static int min(int a, int b); static float min(float a, float b); static int max(int a, int b); static float max(float a, float b); static float dist(int a, int b, int a2, int b2);};# 9 "Entity.h" 2using namespace std;enum ENTITY_STATE { IDLE, MOVING, DEAD };enum INPUT_DEVICE { AUTONOMOUS, KEYBOARD, JOY0, JOY1, JOY2, JOY3 };enum AFFILIATION { NEUTRAL, FRIENDLY, ENEMY };class Entity{public: Entity (); Entity (int col_x, int col_y, int col_w, int col_h);public: static list<Entity*> entity_list; int x, y, w, h; int bx, by, bw, bh;    float vx, vy;    float ax, ay; int life; int damage; ENTITY_STATE state; INPUT_DEVICE input; AFFILIATION affiliation; Animation idle; Animation moving; Animation dead; bool inside (int x,int y,int left,int top,int right,int bottom); bool use_collision_correction; bool colliding;public: static void push (int x, int y, int w, int h); static void delete_dead_entities (); virtual void update (); virtual void render (BITMAP* buffer, int mapxoff = 0, int mapyoff = 0); void load_animation (ENTITY_STATE animation, char* path, int frames); Animation *get_animation (ENTITY_STATE); bool detect_collision (Entity* b); static Entity* get_entity (int number); static int get_count (); void apply_force (float x = 0, float y = 0); void move_to (int x = 0, int y = 0); void move (); void collision_correction (bool on_off = true); int get_x (); int get_y (); int get_w (); int get_h (); float get_vx (); float get_vy (); void set_life (int life); int get_life (); int get_damage (); int get_affiliation (); int collided_tl(int x, int y); int get_user_data(int x, int y, int u);};# 6 "Map.h" 2class Map{public: Map(); static bool load (char* path); static bool load (int map_number); static void update(Entity* target); static void render(BITMAP* buffer); static int get_x(); static int get_y(); static int get_w(); static int get_h(); static void set_xoffset(int x); static void set_yoffset(int y); static void destroy();private: static int mapxoff; static int mapyoff; static BITMAP* background; static int bgx; static int bgy;};# 6 "CrawlerTurret.h" 2class CrawlerTurret : public Entity{public: enum facing_enum {NONE, LEFT, RIGHT, UP, DOWN}; CrawlerTurret (); CrawlerTurret (int x, int y, int w, int h, INPUT_DEVICE = AUTONOMOUS); static void push (int x, int y, int w, int h, INPUT_DEVICE input = AUTONOMOUS); void update (); void render (BITMAP* buffer, int mapxoff = 0, int mapyoff = 0); void crawlerAI ();private: Entity* target; facing_enum facing; facing_enum lastContact; int lastx, lasty; int bufferedVelx, bufferedVely;};



Going to be honest here. I am hella confused.
Holy crap, you can read!
ApochPiQ
ApochPiQ
What is the content of your precompiled header file?



[edit] Wait, wait, wait.

Post the exact command line you are using to invoke G++... I think I might have a suspect for the cause of your problem.
Maverick Programmer
Maverick Programmer
I have before but here it goes:

When compiling:
g++ -c Entity.cpp Entity.hg++ -c Fighter.cpp Fighter.h




When examining the .ii file:
g++ -c -save-temps Fighter.cpp Fighter.h
Holy crap, you can read!
Maverick Programmer
Maverick Programmer
Maverick$ g++ -c Entity.cpp // <- seems to compile fineMaverick$ g++ -c Fighter.cppEntity.h:14: error: multiple definition of ‘enum ENTITY_STATE’Entity.h:13: error: previous definition hereEntity.h:14: error: conflicting declaration ‘IDLE’Entity.h:14: error: ‘IDLE’ has a previous declaration as ‘ENTITY_STATE IDLE’Entity.h:14: error: conflicting declaration ‘MOVING’Entity.h:15: error: ‘MOVING’ has a previous declaration as ‘ENTITY_STATE MOVING’Entity.h:14: error: conflicting declaration ‘DEAD’Entity.h:16: error: ‘DEAD’ has a previous declaration as ‘ENTITY_STATE DEAD’Entity.h:16: error: multiple definition of ‘enum INPUT_DEVICE’Entity.h:18: error: previous definition hereEntity.h:16: error: conflicting declaration ‘AUTONOMOUS’Entity.h:19: error: ‘AUTONOMOUS’ has a previous declaration as ‘INPUT_DEVICE AUTONOMOUS’Entity.h:16: error: conflicting declaration ‘KEYBOARD’Entity.h:20: error: ‘KEYBOARD’ has a previous declaration as ‘INPUT_DEVICE KEYBOARD’Entity.h:16: error: conflicting declaration ‘JOY0’Entity.h:21: error: ‘JOY0’ has a previous declaration as ‘INPUT_DEVICE JOY0’Entity.h:16: error: conflicting declaration ‘JOY1’Entity.h:22: error: ‘JOY1’ has a previous declaration as ‘INPUT_DEVICE JOY1’Entity.h:16: error: conflicting declaration ‘JOY2’Entity.h:23: error: ‘JOY2’ has a previous declaration as ‘INPUT_DEVICE JOY2’Entity.h:16: error: conflicting declaration ‘JOY3’Entity.h:24: error: ‘JOY3’ has a previous declaration as ‘INPUT_DEVICE JOY3’Entity.h:18: error: multiple definition of ‘enum AFFILIATION’Entity.h:26: error: previous definition hereEntity.h:18: error: conflicting declaration ‘NEUTRAL’Entity.h:27: error: ‘NEUTRAL’ has a previous declaration as ‘AFFILIATION NEUTRAL’Entity.h:18: error: conflicting declaration ‘FRIENDLY’Entity.h:28: error: ‘FRIENDLY’ has a previous declaration as ‘AFFILIATION FRIENDLY’Entity.h:18: error: conflicting declaration ‘ENEMY’Entity.h:29: error: ‘ENEMY’ has a previous declaration as ‘AFFILIATION ENEMY’Entity.h:20: error: redefinition of ‘class Entity’Entity.h:32: error: previous definition of ‘class Entity’


So long story short, she still yells at me and tells me I'll never be anything like Dave.
Holy crap, you can read!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.