Header && source file troubles

Hey, I have a few questions about headers and how to declare data structures && classes in them. Also why my header that includes all needed libraries or fragments of libraries like <vector> are not showing up while including only the header file in my source files.

header.hpp
1
2
3
4
5
6
7
8
9
#include <allneeded>

struct power;

union flaw;
enum density;

class flower;


source files look like this:
1
2
3
4
5
#include "header.hpp"
struct power {
...
};
//... 


1
2
3
4
5
#include "header.hpp"
power five;
density six = 6;
//...
int main() { }


i get a lot of errors like power density etc isn't defined.
I've also just included the full declarations of classes and defined whats in unions etc for data structures but I still get errors?

Any ideas of what my problems could be?
Header files should contain the full declaration of the class/struct/union/enum or a simple declaration of variable or function (its prototype). .cpp files should contain the including of this header file and full definition of necessary objects.
All it is not about templates.
Last edited on
I'm doing all of that... but for some reason when I try to compile the damn sources all together I get a ton of errors saying things like everything isn't declared.
edit: doing things like putting the full defs of data structures in the headers and full declarations of classes.
I'm confused.

How should namespaces be used in headers and sources?
Currently I have both full namespaces in source and headers for declarations.
For definitions in the sources i just make it outside the namespaces but with scopes
i.e void ddd::Classname::FunctionName(arguments, ...) { }

What do you mean about

All it is not about templates.
Last edited on
What Syuf is saying is that the struct/class bodies must go in the header.

You are not doing that in the code you posted. You are putting the struct bodies in the cpp file.

1
2
3
4
5
6
7
8
9
10
11
// yourheader.hpp

struct YourStruct
{
  //...
};

class YourClass
{
  void SomeFunction();
};

1
2
3
4
5
6
7
8
// yoursourcefile.cpp

#include "yourheader.hpp"

void YourClass::SomeFunction()
{
  //...
}
use #ifndef
#define
#endif
in your header files?
pre-processor directives.....
Last edited on
My OP was what I was doing. I currently am putting all declarations in headers and definitions in sources. The problem is that when I include the header which includes the necessary libraries(<vector>, <iostream>, etc) in the source files... they still don't recognize it... and say things like std::vector is not declared etc.

I have three sources that all include the same header file. Is that were my problem is?

Disch, yes I'm doing that.
Last edited on
We'll need to see more code. Can you reproduce the problem in a very small example and post the code for it?
Alright, here is some code I just wrote that somewhat mimics what I'm doing in my orig code. The only problem is that the errors it's spitting out aren't even close to my other code. If you want, I will just post that... Actually I will just post it.

def.cpp
1
2
3
4
5
6
7
8
9
#ifndef _BLUE_
#define _BLUE_
#include "testc.hpp"
#endif


int godly::two::Empty::GetR() {
	return r;
}


testc.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <vector>

namespace godly {
	std::vector<int> burger;
	struct chance {
		int taste;
		float smell;
		union {
			int g;
			int r;
			float er;
		} gg;
	};

	namespace two {
		int ImOnOne;
		float AStrongOne;
		
		class Empty {
			int r;
			public:
			void SetR(int rr) {r = rr;}
			int GetR();
		}cc;
	
	}
}


main.cpp
1
2
3
4
5
6
7
8
9
10
#ifndef _BLUE_
#define _BLUE_
#include "testc.hpp"
#endif 
int main() {
	godly::two::ImOnOne = 32;
	std::cout << godly::two::ImOnOne << std::endl;

	return 0;
}


/tmp/cco7h0oD.o:(.bss+0x0): multiple definition of `godly::burger'
/tmp/ccPiKYLb.o:(.bss+0x0): first defined here
/tmp/cco7h0oD.o:(.bss+0x18): multiple definition of `godly::two::ImOnOne'
/tmp/ccPiKYLb.o:(.bss+0x18): first defined here
/tmp/cco7h0oD.o:(.bss+0x1c): multiple definition of `godly::two::AStrongOne'
/tmp/ccPiKYLb.o:(.bss+0x1c): first defined here
/tmp/cco7h0oD.o:(.bss+0x20): multiple definition of `godly::two::cc'
/tmp/ccPiKYLb.o:(.bss+0x20): first defined here
collect2: ld returned 1 exit status
Last edited on
Tried posting original code but got an error too long thing lol.

Someone tell me what's wrong with this one(one above)?

I probably could figure it out as I've used the ifndef with other larger files and it worked. I tried to just take it out of one file as with the header as well but no luck there either.
Your problem is that you are putting global objects in your header. burger, gg, ImOnOne, AStrongOne, and cc are all objects. Since you define them in the header, and since the header is included in multiple cpp files, it's as if you defined them in multiple cpp files.

Objects cannot be defined in multiple cpp files because each cpp file will create it's own copy of the object, then the linker won't know which copy to use.

Your options are to either get rid of globals (recommended)
Or define your globals properly (make them extern in the header, and instantiate them in only 1 cpp file)
How would I do the first option? I'm about to read about the extern keyword also.

Here is my orig header and I will post the errors i'm getting using it.
This is only me second header that I ever used.
I think you will be able to tell what I'm doing when reading it. It's only going to get a lot, lot, lot bigger. I've read that article on how to do headers but any tips on how to divide that up because I'm pretty sure it will span more than 1 file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <SFML/Graphics.hpp>
#include <vector>


namespace _2de {
	class _2deWindow : public sf::RenderWindow {
		std::vector<_2de::Boundaries> boundaries(2);
			
		_2de::Choice choice;

		public:
		void AddBoundaries(float = 0.);
		void AddBoundaries(float = 0., _2de::Choice temp = Coord, _2de::SubChoice tempz = All);
		void AddBoundaries(sf::Vector2f);
		void ModifyBoundaries(int, sf::Vector2f);
		void ModifyBoundaries(int, float, float, float, float);


		};

	class Object : public sf::Sprite {
		std::vector<_2de::Boundaries> boundaries(2);
		
		_2de::Choice choice;
		public:
		void SetChoice(_2de::Choice temp) {choice = temp;}
		void AddBoundaries(float = 0., _2de::Choice temp = Coord, _2de::SubChoice tempz = All);
		void AddBoundaries(sf::Vector2f);
		void ModifyBoundaries(int, sf::Vector2f);
		void ModifyBoundaries(int, float, float, float, float);
	};


	struct Coords {
		float x, y, z, w;
		
	};

	struct Coords2 {
		sf::Vector2f x;
		sf::Vector2f y;
		sf::Vector2f z, w;
	};


	union Coordinates {
		_2de::Coords Coord;
		_2de::Coords2 Coord2;
	};
	enum Choice {
		Coord,
		Coord2,
	}
	enum SubChoice {
		X,
		Y,
		Z,
		W,
		All
	}
		
	struct Boundaries {
		_2de::Coordinates Coordinate;
		_2de::Choice choice;
		_2de::SubChoice subchoice;

	};


	namespace Collision {

	bool CollisionDetection(_2de::Coordinates, _2de::Coordinates, int, int);
	bool CollisionDetection(std::vector<_2de::Coordinates>, std::vector<_2de::Coordinates>);
	bool CollisionDetection(_2de::Object, _2de::Object);
	bool CollisionDetection(_2de::Object, _2de::_2deWindow);


	bool CollisionDetection(_2de::Boundaries Blue, _2de::Boundaries Red);


	}



}


2de.hpp:7: error: ‘Boundaries’ is not a member of ‘_2de’
_2de.hpp:7: error: ‘Boundaries’ is not a member of ‘_2de’
_2de.hpp:7: error: template argument 1 is invalid
_2de.hpp:7: error: template argument 2 is invalid
_2de.hpp:7: error: expected identifier before numeric constant
_2de.hpp:7: error: expected ‘,’ or ‘...’ before numeric constant
_2de.hpp:9: error: ‘Choice’ in namespace ‘_2de’ does not name a type
_2de.hpp:13: error: ‘_2de::Choice’ has not been declared
_2de.hpp:13: error: ‘_2de::SubChoice’ has not been declared
_2de.hpp:13: error: ‘Coord’ was not declared in this scope
_2de.hpp:13: error: ‘All’ was not declared in this scope
_2de.hpp:22: error: ‘Boundaries’ is not a member of ‘_2de’
_2de.hpp:22: error: ‘Boundaries’ is not a member of ‘_2de’
_2de.hpp:22: error: template argument 1 is invalid
_2de.hpp:22: error: template argument 2 is invalid
_2de.hpp:22: error: expected identifier before numeric constant
_2de.hpp:22: error: expected ‘,’ or ‘...’ before numeric constant
_2de.hpp:24: error: ‘Choice’ in namespace ‘_2de’ does not name a type
_2de.hpp:26: error: ‘_2de::Choice’ has not been declared
_2de.hpp:27: error: ‘_2de::Choice’ has not been declared
_2de.hpp:27: error: ‘_2de::SubChoice’ has not been declared
_2de.hpp:27: error: ‘Coord’ was not declared in this scope
_2de.hpp:27: error: ‘All’ was not declared in this scope
_2de.hpp: In member function ‘void _2de::Object::SetChoice(int)’:
_2de.hpp:26: error: ‘choice’ was not declared in this scope
_2de.hpp: At global scope:
_2de.hpp:48: error: member ‘_2de::Coords2 _2de::Coordinates::Coord2’ with constructor not allowed in union
_2de.hpp:67: error: multiple types in one declaration


objects.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <vector>
#include <SFML/Graphics.hpp>
#include "_2de.hpp"


void _2de::_2deWindow::AddBoundaries(float = 0.) {
}
void _2de::_2deWindow::AddBoundaries(float = 0., _2de::Choice temp = Coord, _2de::SubChoice tempz = All) {
}
void _2de::_2deWindow::AddBoundaries(sf::Vector2f) {
}
void _2de::_2deWindow::ModifyBoundaries(int, sf::Vector2f){
}
void _2de::_2deWindow::ModifyBoundaries(int, float, float, float, float) {
}


void _2de::Object::AddBoundaries(float = 0.) {
}

void _2de::Object::AddBoundaries(sf::Vector2f) {
}

void _ModifyBoundaries(int, sf::Vector2f) {
}

void _ModifyBoundaries(int, float, float, float, float) {
}

void _2de::Object::AddBoundaries (float g = 0., _2de::Choice temp = Coord, _2de::SubChoice tempz = All) {
	if(tempz == X && temp == Coord) 
		boundaries[0].Coordinate.Coord.x = g;
	if(tempz == Y && temp == Coord)
		boundaries[0].Coordinate.Coord.y = g;
	if(tempz == Z && temp == Coord)
		boundaries[0].Coordinate.Coord.z = g;
	if(tempz == W && temp == Coord)
		boundaries[0].Coordinate.Coord.w = g;

}


void _2de::_2deWindow::AddBoundaries (float g = 0., _2de::Choice temp = Coord, _2de::SubChoice tempz = All) {
	if(tempz == X && temp == Coord) 
		boundaries[0].Coordinate.Coord.x = g;
	if(tempz == Y && temp == Coord)
		boundaries[0].Coordinate.Coord.y = g;
	if(tempz == Z && temp == Coord)
		boundaries[0].Coordinate.Coord.z = g;
	if(tempz == W && temp == Coord)
		boundaries[0].Coordinate.Coord.w = g;

}


boundstest.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <vector>
#include <SFML/Graphics.hpp>
#include "_2de.hpp"


void _2de::_2deWindow::AddBoundaries(float = 0.) {
}
void _2de::_2deWindow::AddBoundaries(float = 0., _2de::Choice temp = Coord, _2de::SubChoice tempz = All) {
}
void _2de::_2deWindow::AddBoundaries(sf::Vector2f) {
}
void _2de::_2deWindow::ModifyBoundaries(int, sf::Vector2f){
}
void _2de::_2deWindow::ModifyBoundaries(int, float, float, float, float) {
}


void _2de::Object::AddBoundaries(float = 0.) {
}

void _2de::Object::AddBoundaries(sf::Vector2f) {
}

void _ModifyBoundaries(int, sf::Vector2f) {
}

void _ModifyBoundaries(int, float, float, float, float) {
}

void _2de::Object::AddBoundaries (float g = 0., _2de::Choice temp = Coord, _2de::SubChoice tempz = All) {
	if(tempz == X && temp == Coord) 
		boundaries[0].Coordinate.Coord.x = g;
	if(tempz == Y && temp == Coord)
		boundaries[0].Coordinate.Coord.y = g;
	if(tempz == Z && temp == Coord)
		boundaries[0].Coordinate.Coord.z = g;
	if(tempz == W && temp == Coord)
		boundaries[0].Coordinate.Coord.w = g;

}


void _2de::_2deWindow::AddBoundaries (float g = 0., _2de::Choice temp = Coord, _2de::SubChoice tempz = All) {
	if(tempz == X && temp == Coord) 
		boundaries[0].Coordinate.Coord.x = g;
	if(tempz == Y && temp == Coord)
		boundaries[0].Coordinate.Coord.y = g;
	if(tempz == Z && temp == Coord)
		boundaries[0].Coordinate.Coord.z = g;
	if(tempz == W && temp == Coord)
		boundaries[0].Coordinate.Coord.w = g;

}


Objects.cpp:1:31: error: ~/VGame/2de/2de.hpp: No such file or directory
Objects.cpp:30:3: error: invalid suffix "de" on integer constant
Objects.cpp:47:18: error: invalid suffix "de" on integer constant
Objects.cpp:48:34: error: invalid suffix "de" on integer constant
Objects.cpp:48:60: error: invalid suffix "de" on integer constant
Objects.cpp:16: error: ‘sf’ has not been declared
Objects.cpp:16: error: ISO C++ forbids declaration of ‘Vector2f’ with no type
Objects.cpp:16: error: expected ‘;’ before ‘x’
Objects.cpp:17: error: ‘sf’ has not been declared
Objects.cpp:17: error: ISO C++ forbids declaration of ‘Vector2f’ with no type
Objects.cpp:17: error: expected ‘;’ before ‘y’
Objects.cpp:18: error: ‘sf’ has not been declared
Objects.cpp:18: error: ISO C++ forbids declaration of ‘Vector2f’ with no type
Objects.cpp:18: error: expected ‘;’ before ‘z’
Objects.cpp:27: error: ‘sf’ has not been declared
Objects.cpp:27: error: expected ‘{’ before ‘RenderWindow’
Objects.cpp:27: error: invalid type in declaration before ‘{’ token
Objects.cpp:27: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
Objects.cpp:28: error: ‘vector’ is not a member of ‘std’
Objects.cpp:28: error: ‘Boundaries’ is not a member of ‘_2de’
Objects.cpp:28: error: ‘boundaries’ was not declared in this scope
Objects.cpp:28: error: expected ‘}’ before ‘;’ token
Objects.cpp:30: error: expected unqualified-id before numeric constant
Objects.cpp:32: error: expected unqualified-id before ‘public’
Objects.cpp:34: error: ‘_2de::Choice’ has not been declared
Objects.cpp:34: error: ‘Coord’ was not declared in this scope
Objects.cpp:34: error: ‘_2de::SubChoice’ has not been declared
Objects.cpp:34: error: ‘All’ was not declared in this scope
Objects.cpp:35: error: variable or field ‘AddBoundaries’ declared void
Objects.cpp:35: error: ‘sf’ has not been declared
Objects.cpp:36: error: ‘sf’ has not been declared
Objects.cpp:42: error: ‘sf’ has not been declared
Objects.cpp:42: error: expected ‘{’ before ‘Sprite’
Objects.cpp:42: error: invalid type in declaration before ‘{’ token
Objects.cpp:42: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
Objects.cpp:43: error: ‘vector’ is not a member of ‘std’
Objects.cpp:43: error: ‘Boundaries’ is not a member of ‘_2de’
Objects.cpp:43: error: ‘boundaries’ was not declared in this scope
Objects.cpp:43: error: expected ‘}’ before ‘;’ token
Objects.cpp:45: error: ‘Choice’ in namespace ‘_2de’ does not name a type
Objects.cpp:46: error: expected unqualified-id before ‘public’
Objects.cpp:48: error: expected identifier before numeric constant
Objects.cpp:48: error: expected ‘,’ or ‘...’ before numeric constant
Objects.cpp:48: error: default argument missing for parameter 2 of ‘void AddBoundaries(float, int)’
Objects.cpp:49: error: variable or field ‘AddBoundaries’ declared void
Objects.cpp:49: error: ‘sf’ has not been declared
Objects.cpp:50: error: ‘sf’ has not been declared
Objects.cpp:52: error: expected declaration before ‘}’ token


BoundTests.cpp: In function ‘int main()’:
BoundTests.cpp:8: error: expected unqualified-id before ‘[’ token
BoundTests.cpp:9: error: no matching function for call to ‘_2de::_2deWindow::_2deWindow(sf::VideoMode, const char [16])’
_2de.hpp:6: note: candidates are: _2de::_2deWindow::_2deWindow()
_2de.hpp:6: note:                 _2de::_2deWindow::_2deWindow(const _2de::_2deWindow&)
BoundTests.cpp:11: error: ‘_2de::Choice’ is not a class or namespace
BoundTests.cpp:11: error: ‘_2de::SubChoice’ is not a class or namespace
BoundTests.cpp:12: error: ‘_2de::Choice’ is not a class or namespace
BoundTests.cpp:12: error: ‘_2de::SubChoice’ is not a class or namespace
BoundTests.cpp:13: error: ‘_2de::Choice’ is not a class or namespace
BoundTests.cpp:13: error: ‘_2de::SubChoice’ is not a class or namespace
BoundTests.cpp:14: error: ‘_2de::Choice’ is not a class or namespace
BoundTests.cpp:14: error: ‘_2de::SubChoice’ is not a class or namespace


you see how the errors are quite different. This was only test code that was ment to be refactored. Which I actually really want to get to because I have some other features I want to put into the language. Also any tips on what to do better etc?

there's also another source file with a lot of defs for functions. I'm sure you can make what it includes if it you read it. I know now to have every file include like that. I only did that out of frustration because everything wasn't working. It was just like the one I showed above that just included the header file.
Last edited on
Okay the first example you posted is nothing like the 2nd. You have no globals in your 2nd example.

Your problem here is you are trying to use things before they are defined.

Specifically, your 'Choice' enum is used in your _2deWindow class, but your _2deWindow class is defined first. You must define Choice first.

Furthermore, you're missing some semicolons. Choice and Subchoice need to end in a semicolon after the closing brace.

Also, you should not start any identifier with an underscore.
dang I really liked 2de as an identifier. but numbers can't start so I went with _2de lol. I guess I will have to think of another appealing identifier for my namespace.

Umm what's the difference between global and not global for headers?
As in how do I just make simple functions in a header not appear global that aren't in any namespace? or you just saying I must use a namespace etc?
dang I really liked 2de as an identifier.


Why not e2d? ;P

Umm what's the difference between global and not global for headers?


A global variable (or object) is a variable declared outside of any class, struct, or function body. These variables are created at program startup and are destroyed at shutdown... so they exist for the whole life of the program.

The thing that makes globals problematic is that if you give two separate globals the same name, it confuses the linker because it doesn't know which variable you meant to use. Consider this example:

1
2
3
// in A.cpp

int myvar;

1
2
3
4
5
6
7
8
// in B.cpp

int myvar;  // same name as in A.cpp

void myfunction()
{
  myvar = 5;  // which myvar are we setting?  A's or B's?
}


The intention here may seem obvious, but due to the way the language works, it isn't really. Even though A's myvar can't be seen by B during the compile process, both are seen during the linking process, which give you the linker error "multiply defined symbol" (or something like that).


Now once you can understand that, you have to realize that including a header is just a fancy way to copy/paste one file into another. When you #include a header, all the compiler does is start compiling that header as if it were part of the .cpp file. Even something crazy like this is perfectly legal:

1
2
// five.h
5

1
2
// plus.h
+

1
2
3
4
5
6
7
8
9
10
11
12
13
// main.cpp
#include <iostream>

int main()
{
  int myvar = 
#include "five.h"
#include "plus.h"
#include "five.h"
  ;

  std::cout << myvar;  // prints "10"
}


With that in mind, if you define a variable in a header, then #include that header in multiple .cpp files... it's exactly the same as if you were duplicating those variables in each of those cpp files. Therefore the linker gets confused and gives you that error.


As in how do I just make simple functions in a header not appear global that aren't in any namespace?


Global functions aren't a problem. You can prototype a function globally and include it in as many cpp files as you like and you won't have any problems.

The problem only surfaces with global variables/objects.
Topic archived. No new replies allowed.