Skip to main content
gamedev.net
🔒 Locked

global variables

Started by Enselic Oct 8, 2002 at 4:11 PM 15 replies 2.2k views
Original Post
Enselic
Enselic
I've experimented a bit in this subject but i can't seem to get it all together. All i want is a .h file where i keep all the globals like screen width and height. I've come up with this code which apperantly is wrong...
    
/*
globals.h

globals that all the parts of this proram for simplicity should have acces to
*/
#ifndef GLOBALS_H
#define GLOBALS_H

#include <windows.h>
#include "input.h"

extern const DWORD				SCREEN_WIDTH			= 800;
extern const DWORD				SCREEN_HEIGHT			= 600;
extern const DWORD				SCREEN_BIT_DEPTH		= 32;
extern const float				MAX_FPS					= 50.0f;
extern const char			   *APP_NAME				= "Test";

extern CInput				   *g_input = NULL;

#endif

    
[edited by - Enselic on October 8, 2002 5:13:19 PM]
Fruny
Fruny
- consts need not be extern
- you cannot initialise an extern by definition

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Enselic
Enselic
after rewrite and compilation, the whole file globals.h looks like this:


  
/*
globals that all the parts of this proram for simplicity should have acces to
*/

#ifndef GLOBALS_H
#define GLOBALS_H

#include <windows.h>
#include "input.h"
#include "background.h"
#include "playership.h"
#include "log.h"

extern DWORD SCREEN_WIDTH;
extern DWORD SCREEN_HEIGHT;
extern DWORD SCREEN_BIT_DEPTH;
DWORD SCREEN_WIDTH = 800;
DWORD SCREEN_HEIGHT = 600;
DWORD SCREEN_BIT_DEPTH = 32;

extern float MAX_FPS;
float MAX_FPS = 50.0f;
extern char *APP_NAME;
char *APP_NAME = "LifeForceCPP";

extern CInput *g_input;
extern CBackground *g_stars;
extern CBackground *g_bg;
extern CShip *g_player_one;
extern CLog g_log( 200 );

#endif


and produces these errors:


  
--------------------Configuration: LifeForceCPP - Win32 Release--------------------
Compiling...
background.cpp
C:\Övrigt\C++\directx sdk\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
C:\Övrigt\C++\LifeForceCPP\globals.h(26) : error C2143: syntax error : missing '';'' before ''*''
C:\Övrigt\C++\LifeForceCPP\globals.h(26) : error C2501: ''g_stars'' : missing storage-class or type specifiers
C:\Övrigt\C++\LifeForceCPP\globals.h(27) : error C2143: syntax error : missing '';'' before ''*''
C:\Övrigt\C++\LifeForceCPP\globals.h(27) : error C2501: ''g_bg'' : missing storage-class or type specifiers
winmain.cpp
C:\Övrigt\C++\directx sdk\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
Error executing cl.exe.

LifeForceCPP.exe - 4 error(s), 0 warning(s)
Thrump
Thrump
The variables themselves shouldn''t be in your header file. If you include it in more than 1 spot the linker will complain.


extern const Int32 iScreenWidth;


const Int32 iScreenWidth = 800;


The const is not necessary, but is good if you don''t plan on changing the variable.
Xai
Xai
basically, anytime you want to use an "extern" in a header file somewhere, you will also need a non-extern in a cpp file ...

the extern declaration allows you to access / use the variable from multiple places without the compiler trying to create a local copy in each one

the non-extern declaration in some ccp (such as globals.cpp in your case) will tell the compiler DO create the space for these variables, and put it in THIS compilation unit ...

the two bottom errors you are getter are because you have declared g_stars and g_bg to be extern, but have never defined a non-extern version of them ... these are linker errors

also, the fact that you are not getting errors about "redefinition of SCREEN_WIDTH" or "unresolved external SCREEN_WIDTH" is likely because you are not currently including globals.h in more than one compilation unit (a compilation unit is a thing which generates an object file, such as a cpp in your project ...) IF you were #including your global.h in more than ony .cpp you would have problems because you are still telling the compiler to make a copy in each one ...

the person who said you do not need to extern consts is correct, WITH STIPULATIONS, you do not need to extern SCALAR consts ... such as ints, as they will be inlined in the opcodes. On many platforms bools and floats work this way as well, but global c_strings (char arrays) should be externed, even if const ... otherwise you will EITHER get linker errors, OR the compiler will waste space in every compilation unit which uses them ...
olle55
olle55
Im not sure but i think "extern" means that it is defined in an other file. Therefor you need one file to initialize them in. And one to declare them as externs in.

Example:

globals.cpp
char astring = "whatever"; // initialize it in the .cpp file


globals.h
extern char astring; // make it extern in the header or something

You can''t initialize it if you are using "extern" i think.

BUt hey, im just a newbie, dont trust me =)
Enselic
Enselic
"IF you were #including your global.h in more than ony .cpp you would have problems because you are still telling the compiler to make a copy in each one ..."

i thougth that this would not happend since the whole code is in a #ifndef #define - #endif block...

anyway after another rewrite i have this:

globals.cpp

  
#include "globals.h"

const DWORD SCREEN_WIDTH = 800;
const DWORD SCREEN_HEIGHT = 600;
const DWORD SCREEN_BIT_DEPTH = 32;

const float MAX_FPS = 50.0f;
const char *APP_NAME = "LifeForceCPP";

// initialized somewhere else

CInput *g_input = NULL;
CBackground *g_stars = NULL;
CBackground *g_bg = NULL;
CShip *g_player_one = NULL;
CLog g_log( 200 );


globals.h

  
/*
globals that all the parts of this proram for simplicity should have acces to
*/

#ifndef GLOBALS_H
#define GLOBALS_H

#include <windows.h>
#include "input.h"
#include "background.h"
#include "playership.h"
#include "log.h"

extern const DWORD SCREEN_WIDTH;
extern const DWORD SCREEN_HEIGHT;
extern const DWORD SCREEN_BIT_DEPTH;

extern const float MAX_FPS;
extern const char *APP_NAME;

extern CInput *g_input;
extern CBackground *g_stars;
extern CBackground *g_bg;
extern CShip *g_player_one;
extern CLog g_log;

#endif


and still get these errors:

  
Compiling...
background.cpp
C:\Övrigt\C++\directx sdk\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
C:\Övrigt\C++\LifeForceCPP\globals.h(21) : error C2143: syntax error : missing '';'' before ''*''
C:\Övrigt\C++\LifeForceCPP\globals.h(21) : error C2501: ''g_stars'' : missing storage-class or type specifiers
C:\Övrigt\C++\LifeForceCPP\globals.h(22) : error C2143: syntax error : missing '';'' before ''*''
C:\Övrigt\C++\LifeForceCPP\globals.h(22) : error C2501: ''g_bg'' : missing storage-class or type specifiers
[/srouce]
eldee
eldee
okay, first off.. those classes you''re declaring (and incorrectly defining), aren''t known to the compiler.
you didnt include any kind of corresponding headers.. ie CShip.h, for CShip, ect..
you cannot define a variable or object if the keyword
extern is used.
extern implies that it is ALREADY declared and defined elsewhere.
extern just tells the compiler to look in other files for the
original declaration.

as already stated, please read kylotans article on using multi-file
projects.. it''ll be an eye-opener.

-eldee
;another space monkey;
[ Forced Evolution Studios ]

::evolve::

''In C we had to code our own bugs. In C++ we can inherit them.''

mertz
mertz
You need to go here http://lib.daemon.am/Books/ and read up on SAMs
Learn c++ in 21 days, and learn C in 21 days, before you come looking for info at the fourums, because it is all there in these e-books and you will understand it better of you gain insight on your own with the texts. Trust me, self-education is much more beneficial than getting the knowledge from some dude online, who knows the answer onlybecause he nutted it out on his own maby only 5 days ago!

But my two cents: .h files are for the following (STROUSTRUP)

Name: Spaces namespace N { ... }
Type definitions: struct Point { int x, y };
template decs: template class Z;
template defs: template class V { ... };
function declairations: extern int FuntionOne(char * ch);
inline function definitions: inline char get(char* p) {return p;}
data decs: extern int p; // defined, (not declaired) elswhere
constant defs: const float pi = 3.141593;
enums: enum Light {red, yellow, green };
name decs: class Matrix;
includes: #include <dinput>
macro defs: #define VERSION 12
conditional complile directives: #ifdef __GL__
comments: /* How this module works is that the.... */

.c flies are simpler:

ordinary func defs: char get (char* ch) {return p++;}
data defines: int a;
aggregate defintions: short tbl[] = {1,2,3};
unnamed namespaces { ... }
exported template defines export templatef(T t) { ... }

so there u are

Its simple: .h is interface for users .c is the implimentation for creators, mechanics .c = engine .h = steering wheel

[edited by - mertz on October 9, 2002 3:20:26 AM]
If it can be remediedWhy be unhappy about that?If it cannot be remediedWhat is the use of being unhappy about that?It's time to put a stop to this procrastination, later. Do, or do not; there is no try.
Enselic
Enselic
Snce I''m not confortable being considered a newbie, let me explain things and straighten things out.

I''ve been programming as a hobbyist since i was 12 (good ol'' OPL)
I know how to split up files in a projet. Before i considered that it would be great with a varibales that can be accesed everywhere, i passed the objects that needed to be used in another unit as a parameeter i.e. somthing like:

pship->ReadKeys( CInput *input )

I had 13 files with pracitly an object in each (ship, background, logfile handler, input handler, a base object which all graphical objects in the game (the ship for instance) is derived from. That ended up in a whole lot of parameters and i thought that, what the heck, let all objects be accesible from everywhere!

Now since i didn''t have any experience in the extern keyword i thouht that this forum would be a nice place to show my code which didnt work.



Now to some quotes:
"you didnt include any kind of corresponding headers.. ie CShip.h, for CShip, ect"
what do you think "playership.h" does?

"you cannot define a variable or object if the keyword
extern is used"
in my eyes i have not.
my only doubts is the g_log varialbe in that case.
and btw, other units can change the varibales right?
i.e that in playership.cpp is a statment like:
g_input->KeyDown( DIK_AKEY );

"it''ll be an eyeopener"
gaaaah! newbie assumation!!

"Learn c++ in 21 days, and learn C in 21 days, before you come looking for info at the fourums"
gaaaah!! FATAL newbie assumation!!
Just becaues i''m not familiar with one keyword, doesn''t mean that i do not know a shit c++!!!!!
Enselic
Enselic
ah there I go! i fixed it!

the right syntax was

extern class CBackground *g_bg;

which you "i-think-i-know-c++"and "enselic-does-not-know-c++" didn''t had a clue about since that you could easily had said that in the first place....
siaspete
siaspete
I think it was a fair assumption for anyone to make that you weren''t experienced in C++ given your problem.

How to use .c and .h files (and how they work together) was one of the first things I got taught in uni, and one of the first things any decent book teaches. Note that we weren''t saying anything about your general programming skill or experience, just that you were missing some essential C++ knowledge.


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
Stoffel
Stoffel
quote:

i thougth that this would not happend since the whole code is in a #ifndef #define - #endif block...


This quote shows you don''t know the difference between declaration and definition. It''s a subtle thing that a hobbyist may not run into, but it''s fundamental to C and C++. Take it as constructive criticism, and maybe look into checking out a beginning programming book or two.
Alpha_ProgDes
Alpha_ProgDes
moral of this story.

use extern like this.

extern [data type] [variable name]; // in a header (.h) file

then define like this.

[variable name] = [value]; // in a implemenation (.c or .cpp) file


and most importantly read up on C++ !!
Beginner in Game Development?  Read here. And read here.  
Xai
Xai
Alpha was slightly wrong .. the correct version is:

use extern like this.

extern [data type] [variable name]; // in a header (.h) file

then define like any of these.

[data type] [variable name]; // uses default constructor
[data type] [variable name]([constructor parameters]); // uses matching constructor
[data type] [variable name] = [value]; // uses 1 argument constructor
// in a implemenation (.c or .cpp) file

he just left out the data type part from the cpp file ...

ALSO - please note - in SOME implementations, you cannot #include your global.h file in your global .cpp file, because it will not let you define your variables where you have already specified them as extern (hence eldee''s comment about no definition if extern is used). In Visual C++ 6.0 this was true, this was not true in GCC 2.95.3, and I do not know what the C++ standard says about it (IF YOU DO, PLEASE POST)!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.