I am trying to do something like this..I have 3 header files
1. coordinates.h
typedef struct {
float x;
float y;
float z;
}coordinates3D;
2.plane.h
#include "coordinates.h"
typedef struct{
coordinates3D plane;
} plane3D;
3.pointArray.h
#include "plane.h"
plane3D points[] ={
{1.0f,3.74f,0.2354f},
{6.823f,9.234f,1.097f},
};
and a cpp file
4. main.cpp
#include "pointArray.h"
int main(int argc, char **argv)
{
std::cout<<points[1].plane.x;
std::cout<<points[0].plane.y;
}
Everything is working fine but I get a warning message
warning: missing braces around initializer for 'coordinates3D'
[-Wmissing-braces]
I am not sure how to solve this warning ...
It's because of the nested structures. Simply add a couple of braces around the values:
plane3D points[] ={
{ { 1.0f,3.74f,0.2354f } },
{ { 6.823f,9.234f,1.097f } },
};
The outermost is for the array, the next pair is for the plane3D structure, and the next is for the coordinates3D structure.
Related
I want to create a struct that can be used to store 3D coordinates or a linear equation.
Here is the code:
struct myStruct {
union {
// coordinates (3d)
struct {
int x,y,z;
};
// linear equation (ax+b)
struct {
int a,b,x;
};
};
};
And I get the following error:
error: redeclaration of ‘int myStruct::<anonymous union>::<anonymous struct>::x’
I'm on linux mint 18.04, g++ (5.4.0), compile with --std=c++11.
I understand the problem. But have few questions.
I saw something related working on windows, why?
What is the best way to implement it so it works well on both (linux/win)?
Just give them names. This should be fine:
struct myStruct {
union {
struct coordinates { int x,y,z; };
struct linear_equation { int a,b,x; };
coordinates coord;
linear_equation lin_eq;
};
};
I also allowed myself to add some members to the union. However, the two structs have members of same types and quantity, so imho entering the trouble of using a union is questionable.
Just to complement the answer by user463035818. You can simplify your union a bit, by declaring the members directly, e.g.:
struct myStruct {
union {
// coordinates (3d)
struct {
int x,y,z;
} coord;
// linear equation (ax+b)
struct {
int a,b,x;
} lin_eq;
};
};
I've got multiple classes from multiple engineers which I am using and they have the same named structures in the classes. From this I get the error "'struct' type redefinition". How do I get around this?
Example:
// Eng1Class.h
#pragma once
struct Eng1And2SameName
{
unsigned int bottle;
};
class Eng1Class
{
public:
Eng1Class();
~Eng1Class();
};
.
// Eng2Class.h
#pragma once
struct Eng1And2SameName
{
float x, y;
};
class Eng2Class
{
public:
Eng2Class();
~Eng2Class();
};
.
// Main Program
#include "stdafx.h"
#include "Eng1Class.h"
#include "Eng2Class.h"
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
Error: error C2011: 'Eng1And2SameName' : 'struct' type redefinition
According to this Compile error "'struct' type redefinition" although it's the first definition for it the #pragma once should fix the issues, but I still see the error. Any insights you can provide?
No, #pragma once prevents the header files from being included more than once - each is included once -> redefinition.
they have the same named structures in the classes
*header files
The're not defined inside the classes (nested), but they could be:
class Eng1Class
{
public:
struct Eng1And2SameName
{
unsigned int bottle;
};
Eng1Class();
~Eng1Class();
};
Or you could enclose the contents of those headers into two differently named namespaces.
Defining a namespace would help
For example as you said error with same struct definition in same namescope .
Reports error
You can do it by defining namesapce
#include<iostream>
using namespace std;
namespace Eng1 {
struct Eng1And2SameName
{
unsigned int bottle;
};
}
namespace Eng2
{
struct Eng1And2SameName
{
float x, y;
};
}
int main()
{
Eng1::Eng1And2SameName a;
Eng2::Eng1And2SameName b;
return 0;
}
Usually engineers working on the same product are coordinated somehow, at least they will use a common source code repository and a common build. Hence, conflicts should have come up earlier.
"uncoordinated" engineers may happen when they work on different products, and if so, each product could have its own namespace. Thereby, you can combine the products without having conflicts:
// in a header:
namespace Eng1Class {
struct Eng1And2SameName
{
unsigned int bottle;
};
class EngClass
{
public:
EngClass();
~EngClass();
};
}
// in the cpp-file
Eng1Class::EngClass::EngClass() {
cout << "hello, Class 1";
}
// in another (or even the same) header
namespace Eng2Class {
struct Eng1And2SameName
{
float x, y;
};
class EngClass
{
public:
EngClass();
~EngClass();
};
}
// in another (or even the same) cpp-file
Eng2Class::EngClass::EngClass() {
cout << "hello, Class 2";
}
I have a weightedDirectedGraph class and a vertex class in their own header file, weightedDirectedGraph.h. This is it:
#ifndef GRAPH
#define GRAPH
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include "minHeapVertex.h"
using namespace std;
class vertex
{
public:
string data;
list<vertex *> neighbors;
bool known;
int distance, id;
vertex * path;
vertex(string x)
{
data = x;
}
};
class weightedDirectedGraph
{
private:
list<vertex *> vertexList;
vector<vector<int> > edgeWeights; //2D vector to store edge weights
int idCount;
weightedDirectedGraph()
{
idCount = 0;
}
vertex * findVertex(string s);
void dijkstrasAlg(vertex * s);
public:
void addVertex(string x);
//adds bi-directional edges
void addWeightedEdge(string x, string y, int weight);
};
#endif
And I have a minHeapVertex class in a minHeapVertex.h file that will be used as a priority queue in Dijkstra's algorithm. This is the file:
#ifndef MIN_HEAP_VERTEX
#define MIN_HEAP_VERTEX
#include <iostream>
#include <vector>
#include "weightedDirectedGraph.h"
using namespace std;
class minHeapVertex
{
public:
explicit minHeapVertex(int capacity = 100)
:heapArray(capacity + 1), currentSize{ 0 } {}
bool isEmpty() const
{
return (currentSize == 0);
}
vertex * getMinVertex() const; //getting C2143 error here that says I'm missing a semi-colon before '*'. Doesn't make sense though.
void insert(vertex * insertItem);
void deleteMin();
vertex * deleteAndReturnMin();
void makeEmpty()
{
currentSize = 0;
}
void decreaseKey(int index, int decreaseValue);
void remove(int index);
private:
void buildHeap();
void percolateDown(int hole);
vector<vertex *> heapArray;
int currentSize;
};
#endif
I"m getting a lot of compiling errors (with the first one being a C2143 error on the getMinVertex() declaration) and I think it may have something do with trying to access the vertex class in minHeapVertex.h. Can someone show me what I'm doing wrong? Been at it for hours, tried forward declaring the vertex class, tried removing some of the includes "", looked up the error codes and changed things, but nothing is working and just end up with a bunch of errors.
Problem:
OP has a circular dependency between minHeapVertex.h and weightedDirectedGraph.h.
Solution:
Eliminate the dependency.
minHeapVertex.h defines minHeapVertex. minHeapVertex requires vertex.
weightedDirectedGraph.h defines vertex and weightedDirectedGraph. Neither require minHeapVertex.
Three possibilities at this point:
Spin vertex off into its own vertex.h header. minHeapVertex.h and weightedDirectedGraph.h both include vertex.h and not each other.
weightedDirectedGraph.h does not require minHeapVertex.h, so remove #include "minHeapVertex.h" from weightedDirectedGraph.h to break the circle.
forward definition of class vertex; in minHeapVertex.h and the removal of #include "weightedDirectedGraph.h" from minHeapVertex.h.
Solution 1 is preferred. Giving vertex its own header may prevent future problems. 2 is easiest to implement. 3 is pretty stupid and not recommended.
Why circular dependency prevented minHeapVertex from seeing vertex:
To make this easier to see, I've removed all of the other includes from the header files.
Here's my idiotic little test.cpp
#include "weightedDirectedGraph.h"
int main(int argc, char * argsv[])
{
return 0;
}
The compiler will make a little temp file of test.cpp. It will then start parsing until it finds an include directive. The included file is copy-pasted into the temp file at the include statement. So the temp file looks sort of like this:
#define GRAPH
#include "minHeapVertex.h"
using namespace std;
class vertex
{
public:
string data;
list<vertex *> neighbors;
bool known;
int distance, id;
vertex * path;
vertex(string x)
{
data = x;
}
};
class weightedDirectedGraph
{
private:
list<vertex *> vertexList;
vector<vector<int> > edgeWeights; //2D vector to store edge weights
int idCount;
weightedDirectedGraph()
{
idCount = 0;
}
vertex * findVertex(string s);
void dijkstrasAlg(vertex * s);
public:
void addVertex(string x);
//adds bi-directional edges
void addWeightedEdge(string x, string y, int weight);
};
int main(int argc, char * argsv[])
{
return 0;
}
The compiler parses down a little further and sees the include of minHeapVertex.h and copy-pastes so you get this:
#define GRAPH
#define MIN_HEAP_VERTEX
#include "weightedDirectedGraph.h"
using namespace std;
class minHeapVertex
{
public:
explicit minHeapVertex(int capacity = 100)
:heapArray(capacity + 1), currentSize{ 0 } {}
bool isEmpty() const
{
return (currentSize == 0);
}
vertex * getMinVertex() const; //getting C2143 error here that says I'm missing a semi-colon before '*'. Doesn't make sense though.
void insert(vertex * insertItem);
void deleteMin();
vertex * deleteAndReturnMin();
void makeEmpty()
{
currentSize = 0;
}
void decreaseKey(int index, int decreaseValue);
void remove(int index);
private:
void buildHeap();
void percolateDown(int hole);
vector<vertex *> heapArray;
int currentSize;
};
using namespace std;
class vertex
{
public:
string data;
list<vertex *> neighbors;
bool known;
int distance, id;
vertex * path;
vertex(string x)
{
data = x;
}
};
class weightedDirectedGraph
{
private:
list<vertex *> vertexList;
vector<vector<int> > edgeWeights; //2D vector to store edge weights
int idCount;
weightedDirectedGraph()
{
idCount = 0;
}
vertex * findVertex(string s);
void dijkstrasAlg(vertex * s);
public:
void addVertex(string x);
//adds bi-directional edges
void addWeightedEdge(string x, string y, int weight);
};
int main(int argc, char * argsv[])
{
return 0;
}
That gets parsed down to #include "weightedDirectedGraph.h", but fortunately GRAPH has been defined, so most of weightedDirectedGraph.h gets left out. If it hadn't, Everything in weightedDirectedGraph.h would have been defined again and minHeapVertex.h would once again been included over and over and eventually the compiler would crash or tell you to expletive deleted off with a politely worded error message.
Anyway, we can already see what's gone wrong in the above code trace: minHeapVertex needs to know type vertex, but that won't be defined for another 20 lines or so.
If test.cpp had been written as
#include "minHeapVertex.h"
int main(int argc, char * argsv[])
{
return 0;
}
The header files would have been included in the other order and it would have compiled, giving a false sense of security until one day you wrote a program that included weightedDirectedGraph.h first. In other words, the library works until it doesn't, and you didn't change a line of the library's code. Have fun pulling your hair out.
Avoid circular dependencies, circular references and circular saws. All three can rip you up pretty bad.
On to using namespace std; This evil little shortcut takes EVERYTHING in the std namespace and adds it to the global namespace. If you had a function named reverse, now you have to deal with potential overload conflicts with std::reverse. The standard library is huge. There are a huge number of function, class, and variable names that are just itching to overload, override and just plain trample your stuff.
But that's your problem.
Putting using namespace std; in a header make it everyone's problem. Anyone who uses your graphing library has to wade through a minefield, and unless they take a close look at your header file and see that declaration they won't have the slightest clue.
Longer discussion can be found here. Either explicitly namespace everything (std::vector, std::string, ...) or pull in only the pieces you need and know will not conflict with your code with using. Eg:
using std::vector;
using std::string;
Do not put this in your header or someone may wind up wonder why their homebrew vector is freaking out. Probably shouldn't be homebrewing vectors, but you can't save everybody.
I have 1 header file and 2 .cpp files (I've included main.cpp) and work on CodeBlocks. My problem is that compiler not see the errors in the second .cpp file (graph_interface.cpp) when I build it. Do you have any suggestions? Where am I going wrong?.
Simply I get the output even I did the wrong thing in graph_implementation.cpp file:
Target is up to date.
Nothing to be done (all items are up-to-date).
For example, my code in main.cpp
//main.cpp
#include "graph_interface.h"
int main(int argc,char *argv[])
{
return 0;
}
graph_interface.h file
#ifndef GRAPH_INTERFACE_H_INCLUDED
#define GRAPH_INTERFACE_H_INCLUDED
typedef struct{int v;int w;} Edge;
Edge EDGE(int,int);
typedef struct graph *Graph;
Graph GRAPHinit(int);
void GRAPHinsertE(Graph,Edge);
void GRAPHremoveE(Graph,Edge);
int GRAPHedges(Edge[],Graph G);
Graph GRAPHcopy(Graph);
void GRAPHdestroy(Graph);
#endif // GRAPH_INTERFACE_H_INCLUDED
And other cpp file graph_implementation.cpp
#include "graph_interface.h"
using namespace std;
struct graph{
int V;
int E;
int **adj;
};
Graph GRAPHinit(int V){
Graph G=malloc(sizeof *G);
G->V=V;
G->E=0;
G->adj=MATRIXint(V,V,0);
return G;
;// not give anything
}
If you're expecting the line:
;// not give anything
to produce an error, the reason you aren't seeing one is because empty statements are perfectly legal in C++; This line does not contain any error.
// complete, legal C++ program
int main() {
;
}
Using new/delete or malloc/free this way goes against modern C++ practice because it's very difficult to do correctly. Modern practice would be more like:
class Graph {
int V;
Matrix adj;
public:
Graph(int V)
: V(V), adj(V*V, 0)
{}
}
int main() {
Graph g; // automatically initialized and destroyed correctly
// ...
}
#pragma once
#include "Predefined.h"
#include <string>
#include <vector>
using namespace std;
namespace Packets
{
enum { EnumLoginData, EnumPlayerData };
struct LoginData
{
std::string username;
std::string password;
};
struct PlayerData
{
Predefined::Vector2 position;
};
struct MainPacket
{
char type;
int id;
LoginData loginData;
vector<PlayerData> playerData;
};
}
The code above is a single header file called PacketDefines.h. I have a couple of structs prepared as you can see which I will use in another part of my program. Now, the struct PlayerData uses a Predefined::Vector2 object which is a custom struct I created in Predefined.h which is included in the current header file.
The problem is that I get this error on it:
error C2146: syntax error : missing ';' before identifier 'position'
Also, this makes it so that something else in the code, that depends on this struct causes to throw an error:
error C2039: 'position' : is not a member of 'Packets::PlayerData'
This is the Predefined header file:
#pragma once
#include <iostream>
#include <memory>
#include "PacketDefines.h"
// some other includes
using namespace std;
#define LOBBY_MAX_CONNECTIONS 5
#define MAX_DATA_SIZE 512
namespace Predefined
{
struct Vector2
{
Vector2(float valueX = 0.0f, float valueY = 0.0f) : x(valueX), y(valueY) {}
float x;
float y;
};
struct Vector3
{
Vector3(float valueX = 0.0f, float valueY = 0.0f, float valueZ = 0.0f) : x(valueX), y(valueY), z(valueZ) {}
float x;
float y;
float z;
};
struct Connection
{
int ID;
SOCKET socket;
Packets::PlayerData playerData;
};
struct Lobby
{
string lobbyName;
vector<Connection> connectionList;
};
}
I have no idea what is going on since everything is linked like it should as far as I know. I hope my problem is clear and someone can help me solving these errors.
This is a superficial overview, but your "Predefined.h" contains two distinct sections; the first are your Vector classes, the second are more complex classes which contain application logic. To overcome this, you actually need three header files:
Vectors.h -> Should define Vector2 and Vector3, and include none of your application structures
PacketDefines.h -> Should #include "Vectors.h" and nothing else (doesn't need to include Predefined.h).
Connection.h -> Should #include "PacketDefines.h".
Out of scope for this question, I'd also recommend changing your header names to something more meaningful (yes, headers typically declare symbols and define structures; so what?).