Global variable - undeclared identifier

Hello! I have some problems with global variables in my program. When i try to use global variable in one of the classes it just doesn't work - variable is called gRenderer .I need your help to make it running. Code is too long to paste it here so there are links for pastebin files:
http://pastebin.com/edTRwvWZ
http://pastebin.com/1B6Usfrf
http://pastebin.com/ETV0HZUb
http://pastebin.com/YfhLbncc
http://pastebin.com/YpMJxwXK
http://pastebin.com/21gZVDTm
http://pastebin.com/Zpwm9rSj
http://pastebin.com/xWT09ADR
Here is whole project for download:
https://mega.nz/#!v1xznR6A!5K4oVnn4B_7ZPIep_yZmy3V2rUz1Pia3rm99lnv-vAM
There are some variables in Polish so you don't have to blame me for that :P
I used SDL2-2.0.4 for VC and SDL2_image-2.0.1 for VC and it was compiled on Virtual Studio 2015 Enterprise.
Hi,
If they are too long, just post the things that are needed.

This includes :
function main()
complier error messages
the file that produces compiler errors

The "undeclared identifer" error is very common and often very easy to fix. With your code present directly on forum, I am sure we can spot your problem much easier.

And welcome to C++ forum :)
Last edited on
functions.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Headers.h"
#include "CharProp.h"

CharProp gracz;

const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 1024;

SDL_Window* gWindow = NULL;
SDL_Texture* gTextureWoodfloor = NULL;
SDL_Renderer* gRenderer = NULL;
SDL_Surface* gScreenSurface = NULL;
SDL_Surface* Icon = NULL;
/*there are a lot lines of code but they are not needed to solve problem*/


LTexture.h
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
#include "Headers.h"

class LTexture
{
public:
	
	LTexture();
	
	~LTexture();

	bool loadFromFile(std::string path);

	void free();

	void render(int x, int y);

	int getWidth();
	int getHeight();

private:
	SDL_Texture* mTexture;

	int mWidth;
	int mHeight;

};

LTexture.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
#include "LTexture.h"
LTexture::LTexture()
{
}


LTexture::~LTexture()
{
}

bool LTexture::loadFromFile(std::string path)
{
	bool success = true;

	SDL_Surface* loadedSurface = IMG_Load(path.c_str());
	if (loadedSurface == NULL)
	{
		std::cout << " Could not load: " << path.c_str() << " Error: " << SDL_GetError() << std::endl;
		success = false;
	}
	else
	{
		mTexture = SDL_CreateTextureFromSurface(gRenderer, loadedSurface); // Here is the error that "gRenderer: undeclared identifier
		if (mTexture == NULL)
		{
			std::cout << "Could not load Texture image: " << path.c_str() << " Error: " << SDL_GetError() << std::endl;
			success = false;
		}
		SDL_FreeSurface(loadedSurface);
	}
	return success;
}

void LTexture::free()
{
}

void LTexture::render(int x, int y)
{
}

int LTexture::getWidth()
{
	return 0;
}

int LTexture::getHeight()
{
	return 0;
}

When i try to include functions.h in LTexture.h or LTexture.cpp i get this:
1>Main.obj : error LNK2005: "void __cdecl close(void)" (?close@@YAXXZ) already defined in LTexture.obj
1>Main.obj : error LNK2005: "bool __cdecl init(void)" (?init@@YA_NXZ) already defined in LTexture.obj
1>Main.obj : error LNK2005: "bool __cdecl loadMedia(void)" (?loadMedia@@YA_NXZ) already defined in LTexture.obj
1>Main.obj : error LNK2005: "struct SDL_Surface * __cdecl loadSurface(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?loadSurface@@YAPAUSDL_Surface@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in LTexture.obj
1>Main.obj : error LNK2005: "struct SDL_Texture * __cdecl loadTexture(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?loadTexture@@YAPAUSDL_Texture@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in LTexture.obj
1>Main.obj : error LNK2005: "void __cdecl render(struct SDL_Texture *,int,int,int,int,struct SDL_Renderer *)" (?render@@YAXPAUSDL_Texture@@HHHHPAUSDL_Renderer@@@Z) already defined in LTexture.obj
1>Main.obj : error LNK2005: "void __cdecl renderAll(void)" (?renderAll@@YAXXZ) already defined in LTexture.obj
1>Main.obj : error LNK2005: "struct SDL_Window * gWindow" (?gWindow@@3PAUSDL_Window@@A) already defined in LTexture.obj
1>Main.obj : error LNK2005: "struct SDL_Texture * gTextureWoodfloor" (?gTextureWoodfloor@@3PAUSDL_Texture@@A) already defined in LTexture.obj
1>Main.obj : error LNK2005: "struct SDL_Renderer * gRenderer" (?gRenderer@@3PAUSDL_Renderer@@A) already defined in LTexture.obj
1>Main.obj : error LNK2005: "struct SDL_Surface * gScreenSurface" (?gScreenSurface@@3PAUSDL_Surface@@A) already defined in LTexture.obj
1>Main.obj : error LNK2005: "struct SDL_Surface * Icon" (?Icon@@3PAUSDL_Surface@@A) already defined in LTexture.obj
1>Main.obj : error LNK2005: "class CharProp gracz" (?gracz@@3VCharProp@@A) already defined in LTexture.obj
Those are all linker errors indicating multiply defined symbols.

Looking at functions.h, you have the following:
1
2
3
4
5
6
7
CharProp gracz;
...
SDL_Window* gWindow = NULL;
SDL_Texture* gTextureWoodfloor = NULL;
SDL_Renderer* gRenderer = NULL;
SDL_Surface* gScreenSurface = NULL;
SDL_Surface* Icon = NULL;

Those symbols will be defined in EVERY module in which you include functions.h.
You can only define those symbols in ONE .cpp module.
Your header file should declare those symbols as extern
1
2
3
4
5
6
7
extern CharProp gracz;
...
extern SDL_Window* gWindow = NULL;
extern SDL_Texture* gTextureWoodfloor = NULL;
extern SDL_Renderer* gRenderer = NULL;
extern SDL_Surface* gScreenSurface = NULL;
extern SDL_Surface* Icon = NULL;


You also have duplicate defined functions, eg. close(), init(), loadMedia(), render() and renderAll(). You didn't include the header where those are declared, but I'm guessing you have put the DEFINITION of those functions in a header file resulting in multiple definitions. Do NOT put function definitions in a header file.
Last edited on
Try installing some guard macros in functions.h
1
2
3
4
5
6
7
8
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#include "Headers.h"
#include "CharProp.h"

// Your code

#endif 


Add static keyword in front of every global variable or function you can find :
1
2
3
4
5
6
7
8
static const int SCREEN_WIDTH = 1024;
static const int SCREEN_HEIGHT = 1024;
static SDL_Window* gWindow = NULL;
static SDL_Texture* gTextureWoodfloor = NULL;
static SDL_Renderer* gRenderer = NULL;
static SDL_Surface* gScreenSurface = NULL;

// etc 


Edit : if static doesn't work, use extern instead.
Last edited on
@closed account 5a8Ym39o6 - Using the static keyword is going to result in those symbols being private to the compilation unit they are in. That's probably not what the OP wants. I'm sure the OP wants those symbols to be global across all compilation units.
Also, you should also make sure headers included in functions.h get the same treatment.
1
2
#include "Headers.h"
#include "CharProp.h" 
I moved all definitions of functions to other file as you said. Now i got other problem this time with class. I renamed some files but i will provide just necessary ones.
header.h
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
#ifndef header_H
#define header_H

#include <SDL.h>
#include <SDL_image.h>
#include <string>
#include <iostream>
#include "CharProp.h"
//#include "LTexture.h"


CharProp gracz;

const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 1024;

SDL_Window* gWindow = NULL;
SDL_Texture* gTextureWoodfloor = NULL;
SDL_Renderer* gRenderer = NULL;
SDL_Surface* gScreenSurface = NULL;
SDL_Surface* Icon = NULL;

SDL_Surface* loadSurface(std::string path);
SDL_Texture* loadTexture(std::string path);

bool init();
bool loadMedia();

void render(SDL_Texture* RenderSrc, int x, int y, int h, int w, SDL_Renderer* RenderDst);
void renderAll();

void close();
#endif // !header_H 

CharProp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef CharProp_H
#define CharProp_H

#include "header.h"

class CharProp
{
public:
	CharProp();
	~CharProp();

	SDL_Texture* tex;
	//LTexture tex2;


	int x, y, w, h;
private:
	unsigned short blood_level;

};
#endif // !CharProp_H 

And I get 1>e:\gra\visual c++\project1\project1\header.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:\gra\visual c++\project1\project1\header.h(12): error C2146: syntax error: missing ';' before identifier 'gracz'
You have recursive includes.

header.h includes charprop.h at line 8.
charprop.h includes header.h at line 4.

charprop.h has no reason to include header.h, although it does use SDL_Texture at line 12.

You have a few choices (in order of preference):

1) You could replace line 4 with #include "sdl.h" This is the safest approach although it assumes that sdl.h has include guards. A quick google shows that it does.

2) Declare SDL_Texture as forward.
 
  class SDL_Texture;  // forward  


3) Simply assume that sdl.h has already been included (it has). This is the least safe approach, but is readily detected by the compiler if not the case.



Last edited on
I did the 1st thing and it worked but now I have another one... There is class in LTexture.h I included it in header.h because i just use it but i need to include header.h in LTexture.h too because LTexture uses global variables which are declared there and I get again recursive includes. BTW Thanks for your help.
Looking at the ltexture.h in your second post, again there is no reason to include header.h within ltexture.h.

You say ltexture.h uses global variables, however i see no global variables referenced in your class declaration for lTexture. The only dependency I see is a pointer of type SDL_texture at line 21. That's not a global variable. The solutions here are the same as I posted above for charprop.h.

You need to think about and perhaps draw out the hierarchy of your headers. Drawing a map of what includes what will quickly point out any header recursion. Any header that has includes of other headers should include the minimum number of headers (including nested headers) required for compilation.

I sense that you're trying to have one top level header (header.h) that defines everything. That's fine, but you need to avoid having other headers include header.h.

Last edited on
I use global variable in LTexture.cpp Im sorry. When I include header.h there I get errors about redefinition of functions. I feel so dumb asking so trivial questions
Last edited on
As I said before, do NOT include function definitions in a header file, Header files should contain function declarations, not definitions.

You do know the difference between a function declaration and a function definition, right?
1
2
3
4
5
void some_func ();  // A function declaration 
...
void some_func ()  // A function definition
{  // some code
}

My header.h looks like that:
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
#ifndef header_H
#define header_H

#include <SDL.h>
#include <SDL_image.h>
#include <string>
#include <iostream>
#include "CharProp.h"
#include "LTexture.h"

CharProp gracz;

const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 1024;

SDL_Window* gWindow = NULL;
SDL_Texture* gTextureWoodfloor = NULL;
SDL_Renderer* gRenderer = NULL;
SDL_Surface* gScreenSurface = NULL;
SDL_Surface* Icon = NULL;

SDL_Surface* loadSurface(std::string path);
SDL_Texture* loadTexture(std::string path);

bool init();
bool loadMedia();

void render(SDL_Texture* RenderSrc, int x, int y, int h, int w, SDL_Renderer* RenderDst);
void renderAll();

void close();
#endif // !header_H 

I have definitions in other file and I just want to be able to use global variables in LTexture.cpp where are definitions of LTexture class funtions
Last edited on
Line 11, 16-23: These are all variable DEFINITIONS, not declarations. As I have said several times, do not put definitions in a header file.

// header.h
11
12
13
14
15
16
17
extern CharProp gracz;
...
extern SDL_Window* gWindow;
extern SDL_Texture* gTextureWoodfloor;
extern SDL_Renderer* gRenderer;
extern SDL_Surface* gScreenSurface;
extern SDL_Surface* Icon;


You will need to DEFINE these variables (without the extern) in one and only one of your .cpp files.

If you're not going to correct the errors I've already pointed out multiple times, I really can't help you any further.
Last edited on
Ohhhh okay. So now I have only one header which look like this:
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
#ifndef header_H
#define header_H

#include <SDL.h>
#include <SDL_image.h>
#include <string>
#include <iostream>
#include "LTexture.h"
#include "CharProp.h"

extern CharProp gracz;

const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 1024;

extern SDL_Window* gWindow;
extern SDL_Texture* gTextureWoodfloor;
extern SDL_Renderer* gRenderer;
extern SDL_Surface* gScreenSurface;
extern SDL_Surface* Icon;

SDL_Surface* loadSurface(std::string path);
SDL_Texture* loadTexture(std::string path);

bool init();
bool loadMedia();

void render(SDL_Texture* RenderSrc, int x, int y, int h, int w, SDL_Renderer* RenderDst);
void renderAll();

void close();


#endif // !header_H 

There are no definitions now and I got this
1>Main.obj : error LNK2001: unresolved external symbol "class CharProp gracz" (?gracz@@3VCharProp@@A)
1>Main.obj : error LNK2001: unresolved external symbol "struct SDL_Window * gWindow" (?gWindow@@3PAUSDL_Window@@A)
1>Main.obj : error LNK2001: unresolved external symbol "struct SDL_Texture * gTextureWoodfloor" (?gTextureWoodfloor@@3PAUSDL_Texture@@A)
1>Main.obj : error LNK2001: unresolved external symbol "struct SDL_Renderer * gRenderer" (?gRenderer@@3PAUSDL_Renderer@@A)
1>Main.obj : error LNK2001: unresolved external symbol "struct SDL_Surface * gScreenSurface" (?gScreenSurface@@3PAUSDL_Surface@@A)
1>Main.obj : error LNK2001: unresolved external symbol "struct SDL_Surface * Icon" (?Icon@@3PAUSDL_Surface@@A)
1>E:\GRA\Visual C++\Project1\Debug\Gra.exe : fatal error LNK1120: 6 unresolved externals
Now put everything the has extern in the implementation [cpp] file where init(), loadMedia(), etc. are defined. Remove the extern in the implementation file (where the bodies of your functions are) not in the header.
Last edited on
Okay I did that and it works. What should I do to use that extern global variables in method of class. Should I include header.h or what?
EDIT: Okay that works I love you all. Thanks a lot for help and AbstractionAnon I'm sorry for being a bit annoying but I have never used extern before.
Last edited on
Glad you got it working.
Hooray! You are good to go!
Topic archived. No new replies allowed.