Weird linker/compiler errors

Hi guys!

I am trying to make a Clickomania game using SDL. I think everything should be working, but I am getting some very weird, cryptic compiler/linker errors. I tried changing the order of the lines "#include <vector>" and "using namespace std;" and that changes the error messages. I tried all possible combinations, I think, and none worked. This error is with the code exactly as shown below:

Error 4 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 232 1 Clickomania
Error 5 error C2334: unexpected token(s) preceding '{'; skipping apparent function body c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 233 1 Clickomania
Error 15 error C2228: left of '.end' must have class/struct/union c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 208 1 Clickomania
Error 25 error C2228: left of '.end' must have class/struct/union c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 216 1 Clickomania
Error 29 error C2227: left of '->IsAlive' must point to class/struct/union/generic type c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 218 1 Clickomania
Error 33 error C2227: left of '->GetRow' must point to class/struct/union/generic type c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 221 1 Clickomania
Error 31 error C2227: left of '->GetColumn' must point to class/struct/union/generic type c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 220 1 Clickomania
Error 19 error C2227: left of '->Delete' must point to class/struct/union/generic type c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 210 1 Clickomania
Error 3 error C2143: syntax error : missing ';' before '<' c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 232 1 Clickomania
Error 17 error C2143: syntax error : missing ';' before '{' c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 209 1 Clickomania
Error 27 error C2143: syntax error : missing ';' before '{' c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 217 1 Clickomania
Error 16 error C2143: syntax error : missing ';' before ')' c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 208 1 Clickomania
Error 26 error C2143: syntax error : missing ';' before ')' c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 216 1 Clickomania
Error 6 error C2065: 'vector' : undeclared identifier c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 200 1 Clickomania
Error 10 error C2065: 'vector' : undeclared identifier c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 208 1 Clickomania
Error 20 error C2065: 'vector' : undeclared identifier c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 216 1 Clickomania
Error 8 error C2065: 'Neighbors' : undeclared identifier c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 201 1 Clickomania
Error 9 error C2065: 'Neighbors' : undeclared identifier c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 202 1 Clickomania
Error 14 error C2065: 'Neighbors' : undeclared identifier c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 208 1 Clickomania
Error 24 error C2065: 'Neighbors' : undeclared identifier c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 216 1 Clickomania
Error 13 error C2065: 'iter' : undeclared identifier c:\users\ze\documents\visual studio 2012\projects\clickomania\clickomania\Header.h 208 1 Clickomania
Error 18 error C2065: 'iter' : undeclared identifier
Error 23 error C2065: 'iter' : undeclared identifier
Error 28 error C2065: 'iter' : undeclared identifier
Error 30 error C2065: 'iter' : undeclared identifier
Error 32 error C2065: 'iter' : undeclared identifier Error 1 error C2061: syntax error : identifier 'vector'
Error 2 error C2061: syntax error : identifier 'vector'
Error 7 error C2059: syntax error : '>'
Error 11 error C2059: syntax error : '>'
Error 21 error C2059: syntax error : '>'
Error 12 error C2039: 'iterator' : is not a member of '`global namespace''
Error 22 error C2039: 'iterator' : is not a member of '`global namespace''



This is the main .cpp 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include <ctime>
#include <cstdlib>
#include <vector>

using namespace std;

#include "Header.h" 




void Slock(SDL_Surface *screen)
{
	if ( SDL_MUSTLOCK(screen) )
	{
		if ( SDL_LockSurface(screen) < 0 )
		{
			return;
		}
	}
}

void Sulock(SDL_Surface *screen)
{
	if ( SDL_MUSTLOCK(screen) )
	{
		SDL_UnlockSurface(screen);
	}
}

void DrawPixel(SDL_Surface *screen, int x, int y,
			   Uint8 R, Uint8 G, Uint8 B)
{
	Uint32 color = SDL_MapRGB(screen->format, R, G, B);
	switch (screen->format->BytesPerPixel)
	{
	case 1: // Assuming 8-bpp
		{
			Uint8 *bufp;
			bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
			*bufp = color;
		}
		break;
	case 2: // Probably 15-bpp or 16-bpp
		{
			Uint16 *bufp;
			bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
			*bufp = color;
		}
		break;
	case 3: // Slow 24-bpp mode, usually not used
		{
			Uint8 *bufp;
			bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
			if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
			{
				bufp[0] = color;
				bufp[1] = color >> 8; 
				bufp[2] = color >> 16;
			} 
			else
			{
				bufp[2] = color;
				bufp[1] = color >> 8;
				bufp[0] = color >> 16;
			}
		}
		break;
	case 4: // Probably 32-bpp
		{
			Uint32 *bufp;
			bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
			*bufp = color;
		}
		break;
	}
}

void Draw(SDL_Surface* screen, Uint32 colors[DEAD], Board* Board)
{
	for (int row = 0; row < NUMBER_SIDES; row++)
	{
		for (int column = 0; column < NUMBER_SIDES; column++)
		{
			Block* Block = Board->GetBlock(row, column);

			switch (Block->GetColor())
			{
			case BLUE:
				SDL_FillRect(screen, Block->GetRect(), colors[BLUE]);
				break;
			case RED:
				SDL_FillRect(screen, Block->GetRect(), colors[RED]);
				break;
			case GREEN:
				SDL_FillRect(screen, Block->GetRect(), colors[GREEN]);
				break;
			case YELLOW:
				SDL_FillRect(screen, Block->GetRect(), colors[YELLOW]);
				break;
			}
		}
	}
}

int main(int argc, char *argv[])
{
	srand(static_cast<unsigned int>(time(0)));
	if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 )
	{
		printf("Unable to init SDL: %s\n", SDL_GetError());
		exit(1);
	}

	srand(static_cast<unsigned int>(time(0)));
	atexit(SDL_Quit);

	SDL_Surface *screen;
	screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
	SDL_Rect backgroundRect;
	backgroundRect.x = 0;
	backgroundRect.y = 0;
	backgroundRect.h = screen->h;
	backgroundRect.w = screen->w;

	Uint32 white = SDL_MapRGB(screen->format, 255, 255, 255);
	Uint32 black = SDL_MapRGB(screen->format, 0, 0, 0);
	Uint32 colors[DEAD];
	colors[RED] = SDL_MapRGB(screen->format, 255, 0, 0);
	colors[GREEN] = SDL_MapRGB(screen->format, 0, 255, 0);
	colors[BLUE] = SDL_MapRGB(screen->format, 0, 0, 255);
	colors[YELLOW] = SDL_MapRGB(screen->format, 0, 255, 255);

	Board Board;

	SDL_FillRect(screen, &backgroundRect, white);

	if ( screen == NULL )
	{
		printf("Unable to set 640x480 video: %s\n", SDL_GetError());
		exit(1);
	}

	int done = 0;
	while(done == 0)
	{
		SDL_Event event;
		while ( SDL_PollEvent(&event) )
		{
			if ( event.type == SDL_QUIT ) { done = 1; }
			if ( event.type == SDL_KEYDOWN )
			{
				if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }

			}
		}
		Draw(screen, colors, &Board);
		//SDL_FillRect(screen, &backgroundRect, white);
		SDL_Flip(screen);
	}

	return 0;
}

And this is my header. Sorry for the double post, but I reached the max number of characters.

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
#define NUMBER_SIDES 8

#define BLUE 0
#define RED 1
#define GREEN 2
#define YELLOW 3
#define DEAD 4

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define DISTANCE 2
//#include <vector>

//using namespace std;

class Block
{
public:
	Block(int Column, int Row, SDL_Rect Rect)
	{
		m_Color = rand() % DEAD;
		m_Rect = Rect;
		m_Included = false;
		m_Row = Row;
		m_Column = Column;
	}

	int GetColor()
	{
		return m_Color;
	}

	void SetNeighbors(Block* Neighbors[4])
	{
		*m_Neighbors = *Neighbors;
	}

	void SetColor(int Color)
	{
		m_Color = Color;
	}

	int GetRow()
	{
		return m_Row;
	}

	int GetColumn()
	{
		return m_Column;
	}

	void New()
	{
		m_Color = rand() % DEAD;
		m_Included = false;
	}

	void Delete()
	{
		m_Color = DEAD;
		m_Included = false;
	}

	bool IsAlive()
	{
		if (m_Color != DEAD)
			return true;
		else
			return false;
	}

	Block* GetNeighbor(int Number)
	{
		switch(Number)
		{
		case UP:
			return m_Neighbors[UP];
			break;
		case DOWN:
			return m_Neighbors[DOWN];
			break;
		case LEFT:
			return m_Neighbors[LEFT];
			break;
		case RIGHT:
			return m_Neighbors[RIGHT];
			break;
		}
	}

	SDL_Rect* GetRect()
	{
		return &m_Rect;
	}

	bool IsIncluded()
	{
		if (m_Included)
			return true;
		else
			return false;
	}

	void Include()
	{
		m_Included = true;
	}

private:
	int m_Color;
	Block* m_Neighbors[4];
	SDL_Rect m_Rect;
	bool m_Included;
	int m_Column;
	int m_Row;
};

class Board
{
public:
	Board()
	{
		//initialize rects
		for (int row = 0; row < NUMBER_SIDES; row++)
		{
			for (int column = 0; column < NUMBER_SIDES; column++)
			{
				SDL_Rect Rect;

				Rect.x =  (SCREEN_WIDTH - (NUMBER_SIDES * DISTANCE))/(NUMBER_SIDES + 2) * (column + 1);
				if (column != 0)
				{
					Rect.x += DISTANCE;
				}
				Rect.w = (SCREEN_WIDTH - (NUMBER_SIDES * DISTANCE))/(NUMBER_SIDES + 2);


				Rect.y =  (SCREEN_HEIGHT - (NUMBER_SIDES * DISTANCE))/(NUMBER_SIDES + 2) * (row + 1);
				if (row != 0)
				{
					Rect.y += DISTANCE;
				}
				Rect.h = (SCREEN_HEIGHT - (NUMBER_SIDES * DISTANCE))/(NUMBER_SIDES + 2);
				m_Board[row][column] = new Block(column, row, Rect);
			}
		}


		//assign neighbors
		for (int row = 0; row < NUMBER_SIDES; row++)
		{
			for (int column = 0; column < NUMBER_SIDES; column++)
			{
				Block* Neighbors[4];
				if (column == 0)
				{
					Neighbors[LEFT] = 0;
					Neighbors[RIGHT] = m_Board[row][column + 1];
				}
				else if (column == NUMBER_SIDES - 1)
				{
					Neighbors[RIGHT] = 0;
					Neighbors[LEFT] = m_Board[row][column - 1];
				}
				else
				{
					Neighbors[RIGHT] = m_Board[row][column + 1];
					Neighbors[LEFT] = m_Board[row][column - 1];
				}
				if (row == 0)
				{
					Neighbors[UP] = 0;
					Neighbors[DOWN] = m_Board[row + 1][column];
				}
				else if (row == NUMBER_SIDES - 1)
				{
					Neighbors[DOWN] = 0;
					Neighbors[UP] = m_Board[row - 1][column];
				}
				else
				{
					Neighbors[UP] = m_Board[row - 1][column];
					Neighbors[DOWN] = m_Board[row + 1][column];
				}
				m_Board[row][column]->SetNeighbors(Neighbors);
			}
		}
	}

	void Start(int x, int y)
	{
		Block* Selected = WhichBlock(x, y);
		if (Selected)
		{
			vector<Block*> Neighbors = CheckNeighbor(Selected);
			Clear(Neighbors);
			Repopulate(Neighbors);
		}
	}

	void Clear(vector<Block*> Neighbors)
	{
		for (vector<Block*>::iterator iter = Neighbors.begin(); iter != Neighbors.end(); iter++)
		{
			(*iter)->Delete();
		}
	}

	void Repopulate(vector<Block*> Neighbors)
	{
		for (vector<Block*>::iterator iter = Neighbors.begin(); iter != Neighbors.end(); iter++)
		{
			if (!(*iter)->IsAlive())
			{
				int column = (*iter)->GetColumn();
				for (int row = (*iter)->GetRow(); row >= 0; row--)
				{
					if (row == 0)
						m_Board[row][column]->New();
					else
						m_Board[row][column]->SetColor(m_Board[row - 1][column]->GetColor());
				}
			}
		}
	}

	vector<Block*> CheckNeighbor(Block* Selected)
	{
		vector<Block*> Neighbors;

		if (Selected->GetNeighbor(UP) && Selected->GetNeighbor(UP)->GetColor() == Selected->GetColor())
		{
			if (!Selected->GetNeighbor(UP)->IsIncluded())
			{
				Neighbors.push_back(Selected->GetNeighbor(UP));
				Selected->GetNeighbor(UP)->Include();
				CheckNeighbor(Selected->GetNeighbor(UP));
			}
		}
		if (Selected->GetNeighbor(RIGHT) && Selected->GetNeighbor(RIGHT)->GetColor() == Selected->GetColor())
		{
			if (!Selected->GetNeighbor(RIGHT)->IsIncluded())
			{
				Neighbors.push_back(Selected->GetNeighbor(RIGHT));
				Selected->GetNeighbor(RIGHT)->Include();
				CheckNeighbor(Selected->GetNeighbor(RIGHT));
			}
		}
		if (Selected->GetNeighbor(LEFT) && Selected->GetNeighbor(LEFT)->GetColor() == Selected->GetColor())
		{
			if (!Selected->GetNeighbor(LEFT)->IsIncluded())
			{
				Neighbors.push_back(Selected->GetNeighbor(LEFT));
				Selected->GetNeighbor(LEFT)->Include();
				CheckNeighbor(Selected->GetNeighbor(LEFT));
			}
		}
		if (Selected->GetNeighbor(DOWN) && Selected->GetNeighbor(DOWN)->GetColor() == Selected->GetColor())
		{
			if (!Selected->GetNeighbor(DOWN)->IsIncluded())
			{
				Neighbors.push_back(Selected->GetNeighbor(DOWN));
				Selected->GetNeighbor(DOWN)->Include();
				CheckNeighbor(Selected->GetNeighbor(DOWN));
			}
		}
		return Neighbors;
	}

	Block* WhichBlock(int x, int y)
	{
		SDL_Rect First = *m_Board[0][0]->GetRect();
		SDL_Rect Last = *m_Board[NUMBER_SIDES - 1][NUMBER_SIDES - 1]->GetRect();

		//if inside board
		if ((x >= First.x && x < Last.x + Last.w) && (y >= First.y && y < Last.y + Last.h))
		{
			for (int row = 0; row < NUMBER_SIDES; row++)
			{
				if (y >= m_Board[row][0]->GetRect()->y && y < m_Board[row][0]->GetRect()->y + m_Board[row][0]->GetRect()->h)
				{
					for (int column = 0; column < NUMBER_SIDES; column++)
					{
						if (x >= m_Board[row][column]->GetRect()->x && x < m_Board[row][column]->GetRect()->x + m_Board[row][column]->GetRect()->w)
						{
							return m_Board[row][column];
						}
					}
				}
			}
		}
		else
			return 0;
	}

	Block** GetBoard()
	{
		return *m_Board;
	}

	Block* GetBlock(int x, int y)
	{
		return m_Board[x][y];
	}

private:
	Block* m_Board[NUMBER_SIDES][NUMBER_SIDES];
};
I am not sure what I did, but it is working now.
Just some style points :

Organise your code into different files. The declaration of each class goes into it's own file - so have Block.h & Board.h

There should a corresponding .cpp file for each of those - Block.cpp & Board.cpp. Each .cpp file has an #include for it's respective header file, and any other .cpp file has #include 's for which ever classes it needs to use.

Define the functions for your classes in the .cpp file by making use of the scope resolution operator :: For example :

1
2
3
int Block::GetColor() {
   return m_Color;
}


The main.cpp could just be used for creating the objects and calling their functions.

With the functions in main, could they be moved into a relevant class?

You have using namespace std; try NOT to do this, it pollutes the global namespace with untold stuff from std, and can cause naming conflicts - which is what we are trying avoid by using namespaces !!

So put std:: before each std thing, or have statements like this at the top of your file:

1
2
3
4
5
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::vector;


Or try a mixture of both. Lots of people just use std:: exclusively

Be careful about choosing variable names: new & delete are keywords; you have New & Delete, but that is a little too close IMO. Same with Include.

Hope all goes well.
Last edited on
Thanks a lot for those tips! I will certainly incorporate them.

About having a .cpp file for each class, I don't need to do anything else, right? Meaning, are all .cpp files linked together during build or do I still need to include their header on my main one?

And suppose I have a very simple class that only has setters and getters. Should I still use separate files for prototypes and definitions or is it not worth the trouble? If not, should I opt for a .cpp file or a .h?

Thanks a lot!
About having a .cpp file for each class, I don't need to do anything else, right? Meaning, are all .cpp files linked together during build or do I still need to include their header on my main one?

Any file that's attempting to use a class needs to be able to see the definition of that class. This means that it will need to include the header file that contains that definition.

If your main.cpp isn't using those classes, it will not need to include the header.

And suppose I have a very simple class that only has setters and getters. Should I still use separate files for prototypes and definitions or is it not worth the trouble? If not, should I opt for a .cpp file or a .h?

To an extent, this is an issue of personal preference. To me, the benefits of separating out the implementation from the declaration outweigh any advantages of keeping them all in the header file, so I would separate them out into .h and .cpp.

If you do opt to keep them together, then it will need to be in a header file, so that it can be included by other files that want to use your class. So it should be .h.
Last edited on
Thank you very much!
You're welcome :)
Topic archived. No new replies allowed.