PDA

View Full Version : how to declare a global variable right



Cruz
22nd July 2009, 11:09
Hi!

Here is a real C++ noob question. I want to define a global variable that is changable with a slider and accessible to all objects in my project. I tried it like this:



#ifndef CONSTANTS_H
#define CONSTANTS_H

#define PI 3.14159265358979323846
#define G 9.81
#define FPS 90

extern double GAMMA;
double GAMMA = 0.01;

#endif // CONSTANTS_H


Until now I only had the #defined globals and it worked great by including constants.h everywhere I needed them. Now I have a new parameter GAMMA, which is not only global, but also needs to be changed from time to time.

Well, this doesn't work, otherwise I wouldn't be asking. I get a compile error:



debug/passivewalker.o: In function `ZN5QLineC1Eiiii':
c:/Qt/4.4.3/include/QtGui/../../src/gui/painting/qpainter.h:(.data+0x0): multiple definition of `GAMMA'
debug/stickman.o:C:/Qt/2009.03/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/locale_facets.tcc:2497: first defined here
collect2: ld returned 1 exit status


It's not that the name GAMMA is already taken. I tried renaming it to something really special and it didn't help. I would like to keep all globals, constant or not, in one header file. What am I doing wrong?

Thanks
Cruz

yogeshgokul
22nd July 2009, 11:15
extern double GAMMA;
double GAMMA = 0.01;

Well, this doesn't work,

Remove
extern double GAMMA; from here..
Use it everywhere else, where you want this variable.

Cruz
22nd July 2009, 11:41
No, that doesn't work either. Same error about multiple definition.

Lykurg
22nd July 2009, 12:06
Whatever the file locale_facets.tcc is, it already defined a variable called GAMMA. So you might want use a singleton pattern to store your values inside a class or use a namespace.

Cruz
22nd July 2009, 12:13
The problem must be something else. Even if I call my global variable:



#ifndef CONSTANTS_H
#define CONSTANTS_H

#define sgn(a)(((a) < 0) ? -1 : 1)

#define PI 3.14159265358979323846
#define G 9.81
#define TIME_STEP 0.00001
#define SIZE_SCALE 100
#define FPS 100

double RUMPELSTIELZCHEN123 = 0.01;

#endif // CONSTANTS_H



I get the error:



c:/Qt/4.4.3/include/QtGui/../../src/gui/painting/qpainter.h:(.data+0x0): multiple definition of `RUMPELSTIELZCHEN123'
debug/stickman.o:C:/Qt/2009.03/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/locale_facets.tcc:2497: first defined here
collect2: ld returned 1 exit status


locale_facets.tcc does not declare a global variable called RUMPELSTIELZCHEN123.

yogeshgokul
22nd July 2009, 12:24
No, that doesn't work either. Same error about multiple definition.
Please define your global variable in main.cpp (the file contains main function).
And try using the global variable after declaring it as extern.

Cruz
22nd July 2009, 12:33
Yes that works. But this can't be the final solution. I have constants in two places and everywhere I use it I have to specificly declare it as extern. Why doesn't it work in the header file?

Cruz
22nd July 2009, 12:37
I created a new header called globs.h with nothing but GAMMA in it.



#ifndef GLOBS_H_
#define GLOBS_H_

double GAMMA = 0.01;

#endif /* GLOBS_H_ */


If I use the header only in one place, everything works fine. I use it a second time and there you go, multiple definition of GAMMA. It's as if the #ifndef GLOBS_H protection wouldn't be working.

yogeshgokul
22nd July 2009, 12:41
If you want to accumulate all global variables, work like this.
In header globs.h:


extern int glob1;
extern int glob2;


In source globs.cpp:


int glob1 = 0;
int glob2 = 0;

Cruz
22nd July 2009, 12:42
Ok I did that and it works. This is a good solution, but I still don't understand why it didn't work in the first place.

miwarre
23rd July 2009, 08:25
Ok I did that and it works. This is a good solution, but I still don't understand why it didn't work in the first place.
It didn't work because you also put the definition of the variable (double GAMMA = 0.01;) in the .h file; this way, if you #include this .h file in several .c/.cpp files, several GAMMA variables get defined, one for each .c/.cpp file (whence the multiple definitions error).

The final solution works because in the .h file there is only the declaration of the variable (extern double GAMMA;) and this can be repeated any number of times as long as it is always the same; the definition, on the other hand, is put in just one of the .c/.cpp files and then it is unique (=> no error).

Note that the #ifndef GLOBS_H directive does not work in the way you seem to imply: it does not work around including the same .h in multiple .cpp's; it only works around multiple inclusions of the same .h in a single .cpp.

For instance: include1.h includes include2.h and test.cpp includes both include1.h and include2.h;
result: include2.h is included twice and #ifndef blocks the second inclusion.

Does this make things a bit more clear?

Ciao!

Miwarre

Cruz
23rd July 2009, 09:16
Note that the #ifndef GLOBS_H directive does not work in the way you seem to imply: it does not work around including the same .h in multiple .cpp's; it only works around multiple inclusions of the same .h in a single .cpp.

Aaah yes, thank you!

toutarrive
16th February 2010, 11:49
Have look at this link:
http://www.gamedev.net/reference/articles/article1798.asp

musa_yilmaz
16th February 2010, 16:25
thanks, too...