c++ redefinition error even with ifndef - c++

I have several files, and my error is quite odd. I don't know if it might be part of the problem, I work with OpenGL/SDL, with XCode, and I created the files using CMake.
I have files Wall.hpp, Wall.cpp, Player.hpp, Player.cpp, controls.hpp, controls.cpp, main.cpp.
Here is a summarization of the files inclusions:
// Player.hpp
#include <iostream>
class Player{
public :
Player();
int getLifePoints();
int getStaminaPoints();
float getPosX();
float getPosY();
float getPosZ();
void setPosX(float x);
void setPosY(float y);
void setPosZ(float z);
void reducePoints(int damage);
bool isHeroRunning();
void changeHeroRun();
bool isHeroDucking();
void changeHeroDuck();
private :
int lifePoints;
int staminaPoints;
float posX;
float posY;
float posZ;
bool isRunning;
bool isDucking;
};
// Player.cpp
#include "Player.hpp"
using namespace std;
Player::Player(){
this->lifePoints = 100;
this->posX = 0;
this->posY = 0;
this->posZ = 0;
}
int Player::getLifePoints(){
return this->lifePoints;
}
int Player::getStaminaPoints(){
return this->staminaPoints;
}
float Player::getPosX(){
return this->posX;
};
float Player::getPosY(){
return this->posY;
};
float Player::getPosZ(){
return this->posZ;
};
void Player::setPosX(float x){
this->posX=x;
};
void Player::setPosZ(float z){
this->posZ=z;
};
void Player::setPosY(float y){
this->posY=y;
};
void Player::reducePoints(int damage){
this->lifePoints= lifePoints - damage;
}
int lifePoints;
float posX;
float posY;
float posZ;
bool Player::isHeroRunning(){
return isRunning;
}
void Player::changeHeroRun(){
this->isRunning=!this->isRunning;
}
bool Player::isHeroDucking(){
return this->isDucking;
}
void Player::changeHeroDuck(){
this->isDucking=!this->isDucking;
if (isDucking){
this->posZ=this->posZ/2;
} else {
this->posZ=this->posZ*2;
}
}
// Wall.hpp
#ifndef _WALL_H
#define _WALL_H
#include <iostream>
#include <vector>
// Include GLEW
#include <GL/glew.h>
// Include GLFW
#include <GL/glfw.h>
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
class Wall{
public :
Wall(GLfloat x1, GLfloat x2, GLfloat z1, GLfloat z2);
//~Wall();
GLfloat getX1();
GLfloat getX2();
GLfloat getY1();
GLfloat getY2();
GLfloat getZ1();
GLfloat getZ2();
int isInZone(GLfloat x, GLfloat y, GLfloat z);
std::vector<GLfloat> add_wall (std::vector<GLfloat> walls);
private:
GLfloat x1, x2, y1, y2, z1, z2;
};
#endif
// Wall.cpp
#ifndef _WALL_C
#define _WALL_C
// Include GLEW
#include <GL/glew.h>
// Include GLFW
#include <GL/glfw.h>
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "Wall.hpp"
#include <vector>
Wall::Wall(GLfloat x1, GLfloat x2, GLfloat z1, GLfloat z2){
this->x1=x1;
this->x2=x2;
this->y1=y_floor;
this->y2=y_ceiling;
this->z1=z1;
this->z2=z2;
}
#endif
// controls.hpp
#ifndef _MACRO_CONTROLS_C
#define _MACRO_CONTROLS_C
#include <vector>
#include "Wall.hpp"
...
#endif
//controls.cpp
#ifndef _MACRO_CONTROLS_C
#define _MACRO_CONTROLS_C
// Include GLFW
#include <GL/glfw.h>
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
#include <iostream>
#include "controls.hpp"
#include <unistd.h>
#define GetCurrentDir getcwd
#include "Wall.hpp"
...
#endif
//main.cpp
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <list>
#include <vector>
#include <time.h>
#include <typeinfo>
// Include GLEW
#include <GL/glew.h>
// Include GLFW
#include <GL/glfw.h>
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
#include <unistd.h>
#define GetCurrentDir getcwd
#include <common/shader.hpp>
#include <common/texture.hpp>
#include <common/controls.hpp>
#include "Player.cpp"
#include "Turret.hpp"
#include "Wall.hpp"
The code works well until I put the #include "Wall.hpp" in the files controls.hpp or/and controls.cpp .
I am facing the error "redefinition of Wall", and also after this one "Gl.h included before glew.h".

I think the problem is in the way you include the headers in controls.cpp:
Wall.hpp -> definition for class WALL
controls.hpp -> includes wall.hpp
controls.cpp -> includes wall.hpp and controls.hpp
So basically in controls.cpp you include the definitian for class WALL twice; this might be the cause of your error. If you include only controls.hpp, it you should get rid of the error

I don't think there is enough information here to answer exactly why you are seeing the errors you list in the question. It could be caused by a recursive include cycle of some kind although I have not spotted it yet.
However, I think these problems will disappear if you follow some basic C++ hygiene.
Do not include cpp files. You are supposed to compile each of these separately and then use the linker to link them together. I am not familiar with XCode, but most IDEs will be able to do this automatically if the project is set up correctly. It is also quite common to use an external Makefile to handle these tasks.
In the comments you mentioned that when you did not include cpp files from main.cpp, you got a symbol resolution error. This most likely means that the linking step I mentioned above is not being done properly.
Put include guards in every header (hpp) file but not in the cpp files (they are not needed since from step 1, you do not include them).
I have found plenty of problems in the past stemming from incorrect include guards.
The most common one is copy/pasting from one file to another and forgetting to change the macro name.
Another that can occur is where you have multiple directories in your include tree, with files of the same name in two different directories. In that case you need to include the directory name in the guard macro name.
Yet another source of problems can be mismatching #if / #endif pairs. In most cases this will be obvious because the pre-processor will complain, but if you had two sets of mismatching pairs then it might even out with unexpected results. It's good practice to place comments after the #endif to show which guard they are associated with, eg:
#ifndef WALL_H
#define WALL_H
...
#endif /* WALL_H */
Some IDEs (eg. Eclipse CDT) will add these guards in this format automatically.
Do not include leading underscores in the guard macros (or any other macros for that matter) to avoid possible clashes with system defined macros.
In each file (cpp or hpp) include only the hpp files needed to define the classes, functions, variables etc that you are using in that file.
Each cpp file should have a corresponding hpp file, which declares the items defined in the corresponding cpp file. The cpp file should include the hpp file. Anything included by the hpp file does not need to be re-included by the cpp file.
Many C++ programmers insist on the rule that each class should be defined in a separate file. It's not strictly necessary but can make it easier to maintain the code.

Related

Class does not name a type with header guard

Due to error, I needed to implement a header guard in my Header file and Cpp since I have never used it before I don't know what went wrong because on some classes it works and on one it just won't... Originally the problem was bigger, but I think I narrowed it down to the origin of the problem.
LedHandler.h
#ifdef LED_HANDLER_H
#define LED_HANDLER_H
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include <FastLED.h>
/* #include "Led/LedFunction.h"
#include "Led/LedStates.h"
#include "Led/Fading.h" */
class LedHandler {
public:
LedHandler(int length, uint16_t pin);
void clear();
void show();
void setColor(int s, int r, int g, int b);
Adafruit_NeoPixel getStrip();
int getLength();
private:
/* LedStates &currentState;
LedStates &targetState;
Fader<LedStates> &ledFader; */
int length;
Adafruit_NeoPixel strip;
CRGB* leds;
};
#endif
LedHandler.cpp
#ifdef LED_HANDLER_H
#define LED_HANDLER_H
#include <Adafruit_NeoPixel.h>
#include <FastLED.h
#include "Handlers/LedHandler.h"
LedHandler::LedHandler(int length, uint16_t pin) {
...
}
...
#endif
main.cpp
#define FASTLED_ESP8266_NODEMCU_PIN_ORDER
#include <Arduino.h>
#include <Scheduler.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include "Tasks/WifiTask.h"
//#include "Tasks/Networking/UDPTask.h"
//#include "Handlers/GsonHandler.h"
#include "Handlers/LedHandler.h"
LedHandler ledHandler(60, D6);
Error
src\main.cpp:14:1: error: 'LedHandler' does not name a type
LedHandler ledHandler(60, D6);
^
*** [.pio\build\nodemcuv2\src\main.cpp.o] Error 1
As noted by walnut in comments, first issue is that #ifdef should be #ifndef. Now this directive can never be evaluated to true (because this macro is not defined anywhere).
Also, you shouldn't ever put include guards in your cpp file. As the name suggests, you use them to protect files that included in other files, and cpp files should never be included anywhere.
Now, with include guard in your cpp file, the following happens:
Code is read from top to bottom
ifndef is encountered, it is true (LED_HANDLER_H is not yet defined)
LED_HANDLER_H is defined
Other headers are included
"Handlers/LedHandler.h" is included
Now, it's important what #include directive does. It's a simple copy-and-paste of the file content into another file.
#ifdef LED_HANDLER_H from inside LedHandler.h is checked, and it's false (this macro is already defined in step 3)
The whole content of LedHandler.h is skipped due to include guard.

C++ include issue

I am writing a plugin for Autodesk Maya using C++ and have a linker error.
My main class is Maya_Search_Plugin.cpp
#include <Utilities.h>
DeclareSimpleCommand( search_face, PLUGIN_COMPANY, "4.5");
//doIt method is entry point for plugin
MStatus search_face::doIt( const MArgList& )
{
//calls to Maya types/functions and Utilities functions
}
Then I have a Utilities class containing some static methods with header looking like this
#ifndef __Maya_CPP_Plugin__Utilities__
#define __Maya_CPP_Plugin__Utilities__
//#pragma once
//standard libs
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <iostream>
#include <math.h>
//maya libs
#include <maya/MDagPath.h>
#include <maya/MFn.h>
#include <maya/MFileIO.h>
#include <maya/MIOStream.h>
#include <maya/MFnMesh.h>
#include <maya/MFnTransform.h>
#include <maya/MGlobal.h>
#include <maya/MSelectionList.h>
#include <maya/MSimple.h>
#include <maya/MTypes.h>
#include <maya/MPointArray.h>
#include <maya/MObjectArray.h>
class Utilities{
public: static const int max_mov = 50;
public:
static double get_mesh_error(MPointArray, MPointArray, int);
static MStatus translateManipulator(double amount, MObject *path);
static void GetSelected(MObjectArray* objects, MFn::Type type);
};
#endif /* defined(__Maya_CPP_Plugin__Utilities__) */
with the implementation like this
#include <Utilities.h>
double Utilities::get_mesh_error(MPointArray a, MPointArray b, int vertexCount){
...
}
MStatus Utilities::translateManipulator(double amount, MObject *path){
...
}
void Utilities::GetSelected(MObjectArray* objects, MFn::Type type) {
...
}
However I am getting the following error
duplicate symbol _MApiVersion in:
/Users/tmg06qyu/Library/Developer/Xcode/DerivedData/Maya_CPP_Plugin-hjrwvybwlvqyyscbmixdkcpdzjqr/Build/Intermediates/Maya_CPP_Plugin.build/Debug/Maya_CPP_Plugin.build/Objects-normal/x86_64/Maya_Search_Plugin.o
/Users/tmg06qyu/Library/Developer/Xcode/DerivedData/Maya_CPP_Plugin-hjrwvybwlvqyyscbmixdkcpdzjqr/Build/Intermediates/Maya_CPP_Plugin.build/Debug/Maya_CPP_Plugin.build/Objects-normal/x86_64/Utilities.o
ld: 1 duplicate symbol for architecture x86_64
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld failed with exit code 1
Which I presume is a linking error and there is some circular reference somewhere, but I can't work out where it is.
Any help appreciated.
Thanks.
I know this is a year old. But I stumbled on this again a couple minutes ago...
Add
#define MNoVersionString
#define MNoPluginEntry
#include <maya/MFnPlugin.h>
to your header or cpp files where you wrote your plugin code. Include
#include <maya/MFnPlugin.h>
directly in your main.cpp that initializes the plugin.
Most of the examples in maya have the following string:
// This is added to prevent multiple definitions of the MApiVersion string.
#define _MApiVersion
before including anything. For example here.
The issue may happen if you have multiple files which include MFnPlugin.h

CPP include header file results in thousands of errors

When I include this header File "pathfinding.h":
#pragma once
#include <BWAPI.h>
#include "BWAPI/TilePosition.h"
#include <vector>
#include "PathNode.h"
#include "Logger.h"
#include "ArgosMap.h"
#include "MapField.h"
#include "Utils.h"
#include "ComparePathNodePointer.h"
using namespace BWAPI;
class Pathfinding {
private:
std::vector<PathNode*> openList;
std::vector<PathNode*> closedList;
std::vector<Position*> buildpath(PathNode* targetNode);
void expandNode(PathNode* currentNode, MapField* targetField);
ArgosMap* argosMap;
public:
Pathfinding();
~Pathfinding();
std::vector<Position*> getShortestPath(MapField* startField, MapField* targetField);
};
In this header File "UnitAgent.h":
#pragma once
#include <BWAPI.h>
#include <vector>
#include "ArgosMap.h"
#include "Pathfinding.h"
using namespace BWAPI;
class UnitAgent {
protected:
Unit* unit;
UnitType unitType;
int unitID;
std::vector<Position*> trail;
Position target;
public:
UnitAgent(Unit* unit);
std::vector<Position*> getTrail();
Position getTarget();
Position* getPosition();
int getUnitID();
void setTarget(Position target);
void addPositionToTrail(Position* targetLocation);
void moveTo(TilePosition* targetPosition);
};
I get like a million errors mostly error C2143, C2065. But thats not true, the errors do not exist. When I include the header file in another file its all totally fine (except naturally for the stuff that needs the specific header file).
Any Ideas what I should check. Anyone an Idea how i can check my C++ Code, in a way Eclipse checks my java code. I mean why doesnt Visual Studio do that?
This kind of directive should not be in a header file
using namespace BWAPI;
To start with, why do you need all this
#include <BWAPI.h>
#include "BWAPI/TilePosition.h"
#include <vector>
#include "PathNode.h"
#include "Logger.h"
#include "ArgosMap.h"
#include "MapField.h"
#include "Utils.h"
#include "ComparePathNodePointer.h"
using namespace BWAPI;
in pathfinding.h? Just forward declaring ArgosMap, MapField, PathNode, and Position like
class ArgosMap;
class MapField;
class PathNode;
class Position;
is sufficient for pathfinding.h looking at the declaration of Pathfinding class, the stuff above should go to pathfinding.cpp if it is necessary for implementation of Pathfinding methods. The less stuff and dependencies you have in your headers, the easier it will be to debug.
Declarations in pathfinding.h look fine, problem is that some of the methods are not implemented/are not implemented properly. To find out what this methods are, you would need to narrow the scope of the problem - by removing unnecessary dependencies to start with.
Including pathfinding.h in files that do not use it's methods/methods from other headers included would always work fine...

aggregate ‘arcball arcball’ has incomplete type and cannot be defined

I'm having a bit of a problem on the following files:
i have the arcball struct on this file:
#ifndef ARCBALL_H_
#define ARCBALL_H_
#include "ex1.h"
...
extern struct arcball{
float radius;
int x,y;
}arcball;
...
#endif /* ARCBALL_H_ */
and I have the following ex1.h file which includes the arcball.h file:
#ifndef __EX1_H__
#define __EX1_H__
////////////////////////////
// Project Includes
////////////////////////////
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "arcball.h"
////////////////////////////
// OpenMesh Includes
////////////////////////////
#include "OpenMesh/Core/IO/MeshIO.hh"
#include "OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh"
////////////////////////////
// GL Includes
////////////////////////////
#include "GLee.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
...
struct arcball arcball;
#endif
I have to include the ex1.h header since the ex1.h holds includes for glut functions I
use in the arcball.cpp file as well.
and I have to use the arcball.h header in order to use the functions and the struct
defines on that file.
The error I get is the following:
In file included from arcball.h:11:0,
from arcball.cpp:8:
ex1.h:120:16: error: aggregate ‘arcball arcball’ has incomplete type and cannot be defined
make: *** [ex1] Error 1
I don't understand why it is an incomplete type, since I included arcball.h file
Is this an mutual inclusion issue or a struct definition/usage issue?
And how can it be resolved?
Thanks!
The two .h files include each other, causing much of the confusion. That's a terribly bad idea, as the #ifdef around will have different effects depending on which file is included first: in this case, arcball.h -> ex1.h -> arcball.h-but-really-nothing-because-of-the-#ifdef.
Moreover, it is also a bad idea to declare a variable without extern in a header (here ex1.h). That's probably not having the effect that you want. Variables without extern should only be declared in .c files.

What's wrong here? - ISO C++ forbids declaration of 'Circle' with no type

maybe you can help me get this right.
I have a class that is used to draw a circle, but the compiler sends me this message:
In file included from ./Includes.h:19,
from ./Circle.h:8,
from ./Circle.cpp:5:
./GameApp.h:24: error: ISO C++ forbids declaration of 'Circle' with no type
./GameApp.h:24: error: expected ';' before '*' token
Here is the GameApp.h:
#include "Includes.h"
class GameApp {
public:
GameApp();
~GameApp();
void Render();
protected:
void InitGU();
bool Controls();
void *dList; // display List, used by sceGUStart
void *fbp0; // frame buffer
Circle* circle;
};
The Include.h looks like this:
//************************************************************************
// Includes.h
//************************************************************************
#include <malloc.h> //For memalign()
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <stdio.h>
#include <psprtc.h> // for the timer/fps functions
#include <pspctrl.h>
#include <math.h>
// GU
#include <pspgu.h>
#include <pspgum.h>
// Custom
#include "GameApp.h"
#include "Circle.h"
//************************************************************************
// Definitions
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define sin_d(x) (sin((x)*M_PI/180))
#define cos_d(x) (cos((x)*M_PI/180))
#define tan_d(x) (tan((x)*M_PI/180))
//************************************************************************
// structs, datatypes...
#ifndef VERTEX_TYPE_
#define VERTEX_TYPE_
typedef struct {
unsigned int color;
float x, y, z;
} vertex;
#endif
And the Circle.h
//************************************************************************
// Circle.h
//************************************************************************
#ifndef CIRCLE_H_
#define CIRCLE_H_
#include "Includes.h"
class Circle {
public:
Circle(float r1);
~Circle();
void Render();
float r;
float x, y;
float vx, vy;
protected:
vertex* vertices;
int n;
};
#endif
Do not use one-massive-include-to-include-everything (except for precompiled headers). It will almost certainly result in headaches.
Include what you need, and no more. It will solve your problem.
You can forward declare Circle, as DanDan suggested, but fixing your inclusion problem will help you more in the long run.
You may have cyclic inclusion. Use a forward declaration:
class GameApp {
class Cicle;
...
I would check your make file to make sure the build is in the right order then, include both .h in each .h finial try combining the class if there both simple. good luck
Includes.h includes GameApp.h before including Circle.h. So Circle is not yet defined the first time it encounters the definition of GameApp. Like DanDan says forward declare Circle.
In Includes.h, you need to move the #include "Circle.h" ahead of the #include "GameApp.h". Better yet, just include Circle.h directly from GameApp.h. Each header file should include everything it needs to compile directly.
#James is right -- Circle.h #includes GameApp.h, as shown by the original compiler message, and GameApp.h #includes Circle.h via the poorly-thought-out "include-all" Includes.h, but that #include is useless due to the redundant include guard on Circle.h