C++ compile error C2146 and C4430 - c++

Compiler show me 2 errors:
C2146 - syntax error: missing ';' before identifier 'begin'
C4430 - missing type specifier - int assumed. Note: C++ does not support default-int
Errors occur in my "Globals.h" file, at line 5.
It's here:
#pragma once
#include "Load.h"
#include "SortStream.h"
extern Load begin;
extern int sort_by;
extern int sort_type;
extern vector<Flight> all_flights;
extern SortStream sort_stream;
My "Globals.cpp" file looks like:
#include "Globals.h"
Load Begin;
int sort_by;
int sort_type;
vector<Flight> all_flights;
SortStream sort_stream;
And ofc, here is "Load.h" file:
#pragma once
#include <vector>
#include "Flight.h"
#include "Globals.h"
using namespace std;
class Load {
std::string path;
vector<Flight> allFlights;
public:
Load();
std::string get_path();
vector<Flight> get_allFlights();
void set_path(std::string p);
void set_allFlights(vector<Flight> v);
void load_flights();
};
And "SortStream.h" file:
#pragma once
#include <vector>
#include "Flight.h"
using namespace std;
class SortStream {
vector< vector < Flight > > layout;
int switchNum;
int iterationNum;
int compareNum;
public:
SortStream();
vector< vector < Flight > > get_layout();
int get_switchNum();
int get_iterationNum();
int get_compareNum();
void set_layout(vector< vector < Flight > > v);
void set_switchNum(int n);
void set_iterationNum(int n);
void set_compareNum(int n);
};
Does anyone knows reason? Tnx in advance

To see the fail, you have to understand how #includes work. Each #includeis replaced by a copy of the included file.
Looking at Load.h
#pragma once
#include <vector> <-- paste vector in here
#include "Flight.h" <-- paste Flight.h in here
#include "Globals.h" <-- paste Globals.h in here
using namespace std;
class Load {
std::string path;
vector<Flight> allFlights;
public:
Load();
std::string get_path();
vector<Flight> get_allFlights();
void set_path(std::string p);
void set_allFlights(vector<Flight> v);
void load_flights();
};
Let's paste in Globals.h and watch what happens:
#pragma once
#include <vector> <-- paste vector in here
#include "Flight.h" <-- paste Flight.h in here
//Globals.h begins here
#pragma once
#include "Load.h" <-- would paste Load.h in here, but it's protected by #pragma once
and will not be pasted in again
#include "SortStream.h" <-- paste SortStream.h in here
extern Load begin;
extern int sort_by;
extern int sort_type;
extern vector<Flight> all_flights;
extern SortStream sort_stream;
// end of Globals.h
using namespace std; <-- off topic: Very dangerous thing to do in a header
class Load {
std::string path;
vector<Flight> allFlights;
public:
Load();
std::string get_path();
vector<Flight> get_allFlights();
void set_path(std::string p);
void set_allFlights(vector<Flight> v);
void load_flights();
};
In this case we can see that Load begin; is referenced before Load is defined. Boom.
Circular references are almost always bad and in this case, it is lethal. In other words, Tarik Neaj for the win.
Load.h has no need for anything defined in Globals.h, so remove the include to break the cycle.

Related

extern vector created in constructor

I have a class Team and a class Ball and I create a vector in constructor of Team that is filled with objects of another class called Player. So I want to use this vector in the class Ball but even though I define it as extern (public) compiler keeps telling me that I have undefined reference to team that is my vector. Here follows the code of Team.cpp and Ball.cpp
Team.h
#define TEAM_H
#include <iostream>
#include <vector>
#include "Player.h"
using namespace std;
extern vector<Player> team;
class Team {
public:
Team();
void fillTeamVector(vector<Player>&);
private:
string teamName;
int faults;
int passes;
int goals;
};
#endif // TEAM_H
Team.cpp
#include "Team.h"
#include <vector>
#include <iostream>
#include "Player.h"
#include "Attacker.h"
#include "Defender.h"
#include "Ball.h"
Team::Team()
{
extern vector<Player> team;
fillTeamVector(team);
}
void Team::fillTeamVector(vector<Player>& team){
// do stuff and store them on vector team
}
And here follows the code for Ball.h note that I commented all the methods that don't affect the problem.
#ifndef BALL_H
#define BALL_H
#include "Player.h"
class Ball
{
public:
Ball();
Player* current;
Player* previous;
/*void setX_ball(int);
int getX_ball() const;
void setY_ball(int);
int getY_ball() const;*/
void assign();
//void changeCurrentToPrevious();
//void changeNextToCurrent(Player*);
private:
int X_ball;
int Y_ball;
};
#endif // BALL_H
Here is the code for Ball.cpp note that in method assign if I create a new (and obviously different vector of Player named team it will compile correctly)
#include "Ball.h"
#include "Team.h"
#include "Player.h"
extern vector<Player> team;
Ball::Ball()
: X_ball(2),
Y_ball(5)
{
current = NULL;
previous = NULL;
}
void Ball::assign(){
//vector<Player> team;
int x;
int y;
x=(team[0].getX())-X_ball;
y=(team[0].getY())-Y_ball;
int min=x+y;
int k=0;
for (int i=1; i<team.size(); i++){
x=(team[i].getX())-X_ball;
y=(team[i].getY())-Y_ball;
int sum=x+y;
if(sum<min){
k=i;
}
}
current = &team[k];
}
By doing
extern vector<Player> team;
you only declare the variable.
In one source file you must actually define the variable:
vector<Player> team;
Note the lack of extern in the definition.
Also note that this has to be done in the global scope, since you want a global variable. So it has to be defined outside of any functions or classes or namespaces.

VC++ undeclared identifier

Why this in Client.cpp file I'm getting error C2065:'TunnelContainer': undefined identifier?
Client.cpp code:
#include "stdafx.h"
#include "GClientLib.h"
using namespace GClientLib;
int _tmain(int argc, _TCHAR* argv[])
{
SettingsReader^ settings = gcnew SettingsReader();
SocketToObjectContainer^ STOContainer = gcnew SocketToObjectContainer();
TunnelContainer^ tunnels = gcnew TunnelContainer();
timeval time;
time.tv_sec = 0;
time.tv_usec = 300000;
....
GClientLib.h code fragment:
#include "Structures.h"
#include "Globals.h"
#include "SettingsReader.h"
#include "SocketToObjectContainer.h"
#include "SocketToSocketContainer.h"
#include "TunnelContainer.h"
Updated. SocketToSocketContainer.h
#ifndef SocketToSocketContainer_H
#define SocketToSocketContainer_H
#include <cliext/utility>
#include <cliext/list>
#include <cliext/algorithm>
namespace GClientLib {
ref class SocketToSocketContainer {
private:
cliext::list<cliext::pair<int, int>> sarasas;
public:
SocketToSocketContainer(void);
void Add(int, int);
int Find(int);
void Delete(int);
};
};
#endif
GclientLib is lib project, used in Client application. Build on Visual Studio 2013 C++/CLI enabled
TunnelContainer.h code:
#ifndef GClientLib_H
#define GClientLib_H
#include <cliext/utility>
#include <cliext/list>
#include <cliext/algorithm>
namespace GClientLib {
enum TunnelStatus
{
JUNGIASI = 1, //Uzmezgamas rysys tarp klientu
LAUKIA_PROGRAMOS = 2, // Laukia kol prisijungs norima kliento porgramine iranga
KOMUNIKACIJA = 3 // Tuneliu vyksta komunikacija
};
ref struct Tunnel
{
int tag; //Tunelio zyme
int dport; //Prievadas, prie kurio jungesi
int clientid; //Kliento ID su kuriuo sujungta
int sport; //Vietinis prievadas
int serverSocket; //Socketas, prie kuris priima duomenu srauta
int status; // Sujungimo statusas (Jungiasi, prisjungta, laukia jungties)
};
ref class TunnelContainer {
private:
// Tuneliu sarasas
cliext::list<cliext::pair<int, Tunnel^>> sarasas;
public:
// Konstruktorius
TunnelContainer();
// Pridedamas naujas tunelis. PERRASO statusa i JUNGIAMASI
Tunnel^ Add(Tunnel^ tunelis);
// Pridedamas naujas tunelis. Statusa nustato i JUNGIAMASI
Tunnel^ Add(int tag, int dport, int clientid, int sport, int serverSocket);
// Tunelio paieska pagal tag
Tunnel^ Find(int tag);
// Salina tuneli pagal tag
Tunnel^ Remove(int tag);
// Keicia tunelio statusa
void ChangeStatus(int tag, TunnelStatus status);
};
};
#endif
UPDATE
After moving TunnelContainer.h into first position getting this error in ToServerSocket.h file:
Error 1 error C2143: syntax error : missing ';' before '^' line 16
Error 2 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int line 16
ToServerSocket.h code:
#ifndef ToServerSocket_H
#define ToServerSocket_H
#include <iostream>
#include "gNetSocket.h"
#include "ServerSocket.h"
#include "OutboundSocket.h"
namespace GClientLib {
ref class ToServerSocket : public gNetSocket {
private:
char *commandBuffer;
line 16 --->TagGenerator^ tag;
SocketToObjectContainer^ STOC;
SettingsReader^ settings;
public:
ToServerSocket(string ip, string port, fd_set* skaitomiSocket, fd_set* rasomiSocket, fd_set* klaidingiSocket, SocketToObjectContainer^ STOC, SettingsReader^ settings);
virtual int Send(char* data, int lenght) override;
virtual void Recive(SocketToObjectContainer^ container) override;
virtual void Connect() override;
virtual void Reconnect() override;
void CommandList(int page);
void CommandListAck(int rRecv);
void CommandHello();
void CommandHelp();
void CommandInitConnect(int id, int port, SocketToObjectContainer^ container);
void CommandConnect(SocketToObjectContainer^ container);
void CommandClear();
void CommandBeginRead(SocketToObjectContainer^ container);
void CommandClientConnectAck(SocketToObjectContainer^ container);
void CommandInitConnectAck();
void CommandJsonList(int page, SOCKET socket);
void CommandJsonListAck(int rRecv, SocketToObjectContainer^ container);
void CommandJsonInitConnect(int id, int port, SOCKET socket);
void CommandJSONConnect(SocketToObjectContainer^ container);
void CommandJsonInitConnectAck();
int GenerateTag();
};
};
#endif
you probably have a syntax error or missing ; or missing closing " in the include before that, "SocketToSocketContainer.h".
#include is a precompiler statement, all it does is include the content of the given file into the main file; it is your task to make sure that the result is a valid code. So if one include has an incomplete statement, the content of the second include continues that statement.
Edit: It could be even further up in the list - any open or incorrect #IFDEF in any include could remove the whole rest
I have found my mistake. GClientLib_H was already defined.
#ifndef GClientLib_H
#define GClientLib_H
Changed to
#ifndef TunnelContainer_H
#define TunnelContainer_H
Now everything is working. Thank you for quick responses

Redefinition of struct error, I only defined it once

I really don't understand how to fix this redefinition error.
COMPILE+ERRORS
g++ main.cpp list.cpp line.cpp
In file included from list.cpp:5:0:
line.h:2:8: error: redefinition of âstruct Lineâ
line.h:2:8: error: previous definition of âstruct Lineâ
main.cpp
#include <iostream>
using namespace std;
#include "list.h"
int main() {
int no;
// List list;
cout << "List Processor\n==============" << endl;
cout << "Enter number of items : ";
cin >> no;
// list.set(no);
// list.display();
}
list.h
#include "line.h"
#define MAX_LINES 10
using namespace std;
struct List{
private:
struct Line line[MAX_LINES];
public:
void set(int no);
void display() const;
};
line.h
#define MAX_CHARS 10
struct Line {
private:
int num;
char numOfItem[MAX_CHARS + 1]; // the one is null byte
public:
bool set(int n, const char* str);
void display() const;
};
list.cpp
#include <iostream>
#include <cstring>
using namespace std;
#include "list.h"
#include "line.h"
void List::set(int no) {}
void List::display() const {}
line.cpp
#include <iostream>
#include <cstring>
using namespace std;
#include "line.h"
bool Line::set(int n, const char* str) {}
void Line::display() const {}
You need to put include guards in your headers.
#ifndef LIST_H_
#define LIST_H_
// List.h code
#endif
In list.cpp, you are including both "line.h" and "list.h". But "list.h" already includes "line.h" so "list.h" is actually included twice in your code. (the preprocessor is not smart enough to not include something it already has).
There are two solutions:
Do not include "list.h" directly in your list.cpp file, but it is a practice that does not scale: you have to remember what every of your header file includes and that will be too much very quickly.
use include guards, as explained by #juanchopanza
You are including "line.h" twice, and you don't have include guards in your header files.
If you add something like:
#ifndef LINE_H
#define LINE_H
... rest of header file goes here ...
#endif
to your header files, it will all work out fine.

Classes as parameters error

In Weapon.h, when I try and take a class 'Entity*' as a parameter, it says "Syntax error: identifier 'Entity'" when I compile. Additionally when I roll over the text 'target', Visual C++ Express 2010 gives me the text " *target". The Entity class is fine and I'm pretty sure it's included correctly.
(I won't post Player.h as it's unnecessary - see Library.h - but it has a header guard and includes Entity.h)
Library.h:
#ifndef _LIBRARY_
#define _LIBRARY_
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdarg>
#include <vector>
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <map>
#include <exception>
#include <sstream>
//file includes
#include "Globals.h"
#include "Player.h"
#include "Exception.h"
#include "Weapon.h"
#include "Armour.h"
#include "Consumable.h"
//prototypes that require "Library.h"
bool Poglathon(std::vector<std::string>& text,Player *player);
bool PoglathonTown(std::vector<std::string>& text,Player *player);
std::map<std::string,Weapon*> init_weapons(void);
std::map<std::string,Armour*> init_armour(void);
std::map<std::string,Consumable*> init_consumables(void);
#endif //__LIBRARY__
Weapon.h:
#ifndef _WEAPON_H_
#define _WEAPON_H_
#include "Shopable.h"
class Weapon : public Shopable{
private:
int Damage;
public:
Weapon(int c,int d,std::string n) : Shopable(c,n),Damage(d){}
std::string getDesc() const{
return getName()+"\t"+tostring(Damage)+"\t"+tostring(Cost);
}
int getDamage() const{return Damage;}
int DamageTarget(Entity* target){
int DamageDealt = 0;
//do damage algorithm things here
return DamageDealt;
}
};
#endif
Shopable.h:
#ifndef _SHOPABLE_H_
#define _SHOPABLE_H_
#include "Library.h"
class Shopable{
protected:
std::string Name;
int Cost;
std::string Description;
public:
Shopable(int c, std::string n):Cost(c),Name(n){}
std::string getName() const{return Name;}
int getCost() const {return Cost;}
virtual std::string getDesc() const = 0;
};
#endif
Entity.h:
#ifndef _ENTITY_
#define _ENTITY_
#include "Library.h"
#include "Weapon.h"
#include "Armour.h"
#include "Consumable.h"
class Entity{
public:
void printStats() const;
void heal(double health);
std::string name;
protected:
//player stats
double str; //strength
double wis; //wisdom
double ref; //reflex
double hp; //health points
double maxHp; //maximum health points
double i; //initiative
double inte; //intelligence
double c; //courage
int gold; //gold
int xp; //experience
int ap; //armour points
int wd; //weapon damage
int lvl; //level
int sp; //skill points
Weapon* weapon;//weapon
Armour* cArmour;//current armour
};
#endif
In C++, classes must be declared before they are referenced. You are #include-ing Weapon.h in Entity.h, but at that point, the compiler doesn't know about the existence of class Entity.
You will either need to change the order in which things are declared, or add a forward declaration "above" class Weapon. It can simply be:
class Entity;
That tells the compiler that there is such a name as Entity. However, it doesn't tell it anything about what members it has, so you can't actually do anything with it, other than declare variables of Entity * and Entity &, and pass them around.
Your headers include each other because your classes refer to each other. (But your compiler doesn't suffer from a stackoverflow because of your include guards - that's a good thing!)
You should arrange your header files hierarchically, ie there are files at the 'top' which #include nothing and files 'below' which include some of the top ones and so-on down the hierarchy. But at no point should there be 'loops'.
In order to break your loops in your code, any classes that refer to each other should forward declare any mutual dependencies and only refer to dependency names and not their members.
e.g.
Entity.h
class Weapon;
class Entity{
...
Weapon* weapon;
};
Weapon.h
class Entity;
class Weapon{
...
int DamageTarget(Entity* target);
};
Notice how Weapon.h only refers to Entity*.
You will need to define int Weapon::DamageTarget(Entity* target) in Weapon.cpp
#include <entity.h>
Or forward-declare only in the header
class Entity;
This makes compilation a bit faster (you still need to include it to use in the implementation).
Weapon.h doesn't #include Entity.h, or anything that recursively includes it. Therefore, it doesn't know about the class Entity.

C++ Does not name to a type

This might be an easy question, but I cannot figure out why the compiler it's giving me this error. I have two classes. Agent and Environment. WHen I try to add an object of type Agent in my Environment class I get Agent does not name to a type error. I am including Agent.h in my Environment.h class
#ifndef AGENT_H_INCLUDED
#define AGENT_H_INCLUDED
#include <vector>
#include <iostream>
#include "Environment.h"
using namespace std;
class Agent{
public:
Agent(bool s);
vector<int> getPercept();
void setPercept(vector<int> p);
void goForward();
void turnRight();
void turnLeft();
void clean();
void paint();
void refuel();
bool needsRefuel();
void turnOn();
void turnOff();
bool isActive();
void move();
int getCurX();
int getCurY();
char getCurDir();
void setCurrentPosition(int x, int y, char d);
private:
vector<int> percept;
int actions;
int performance;
char direction;
bool isOn;
int curX;
int curY;
char curDir;
};
#endif // AGENT_H_INCLUDED
/*************************/
#ifndef ENVIRONMENT_H_INCLUDED
#define ENVIRONMENT_H_INCLUDED
#include <vector>
#include <iostream>
#include "Agent.h"
using namespace std;
class Environment{
public:
Environment(vector<vector<char> > roomData);
Environment(vector<vector<char> > roomData, vector<int> status);
void setRoomData(vector<vector<char> > roomData);
bool isSimulationComplete();
void isAgentHome();
vector<int> sendLocationStatus();
void printEnvironment();
void setAgentHome(int x, int y);
vector<int> getAgentPercept();
void setAgentPercept(vector<int> status);
void setAgentPosition(int x, int y, char p);
vector<int> sendAgentPercept();
void calculateAgentPercept();
private:
vector<vector<char> > room;
vector<int> agentPercept;
bool simulationComplete;
int agentHomeX;
int agentHomeY;
int agentX;
int agentY;
char agentDir;
Agent agent; ////ERROR IS HERE
};
#endif // ENVIRONMENT_H_INCLUDED
Your agent.h includes environment.h. The agent.h file is parsed in order from top to bottom, so when environment.h is parsed, the compiler doesn't know what an Agent is. There appears to be no reason to incude environment.h in agent.h.
Apart from what the comments already said, you can't have two header files include each other. There is no reason for Agent.h to include Environment.h, so if a .cpp file includes Agent.h first, it'll fail (since it will first go through Environment.h, which requires Agent).
IF you have a situation where two header files depend on each other's definitions, use forward declarations where you can, or split your header files up into more header files.