My globals from the main header are used everywhere and the program runs without any odd behaviour. |
I've had this work on really old compilers (VS4 mostly -- back when I was first starting out and was doing the whole global thing like you are). More recent compilers shouldn't let you get away with it, though. What compiler are you using?
Was this just my compiler being poka yoke, or am I to expect problems in the future by miss-using globals? |
Expect problems in the future.
Also, b) All globals (the point of this topic) are declared in a single header file (the "main" header), which (as always) is guarded. |
Guarding your header doesn't do anything for this particular problem. As Nisheeth said, it just prevents a header from being included more than once in the same cpp file.
Look at it this way. Imagine you have two separate cpp files with two separate globals who just happen to have the same name:
1 2 3 4 5 6 7 8
|
// a.cpp
int myglobal = 0;
void a_func()
{
// do something with myglobal
}
|
1 2 3 4 5 6 7 8
|
// b.cpp
int myglobal = 1;
void b_func()
{
// do something with myglobal
}
|
From this code, it seems like the programmer's intent was to have two unique variables. The fact that they share the same name is merely a coincidence. a's global and b's global appear to be two separate variables.
What you have to remember with #include is that it's basically just a copy/paste operation. All the compiler does when it comes across an #include line is start compiling the header file as if it were copy/pasted into the cpp file. The end result is that putting a global in a header looks exactly the same to the compiler as the above code snippit.
Let's replace the above with a simple header:
1 2
|
// header.h
int myglobal;
|
1 2 3 4 5 6
|
//a.cpp
#include "header.h" // the compiler will simply replace this line with the header's contents
// effectively declaring int myglobal; right here
//...
|
1 2 3 4 5
|
//b.cpp
#include "header.h" // same thing
//...
|
So as you can see, it's just as confusing to the compiler and linker. They see multiple cpp files wanting to create what appears to be individual variables which just happen to share the same name and they freak out and complain.
c) Using the "extern" is a bit of a hassle, isn't it? |
I suppose. But use of shared globals is such a rarity that it practically never comes up (or rather, it
should be such a rarity).
I'd have to declare them as "extern" in the main header and then "redefine" them in a cpp file. |
Yup. There's a shortcut you can use with macros though. Since you seem to be committed to sticking with globals...
1 2 3 4 5 6 7 8
|
// globals.h -- or whatever header has your globals
#ifndef GLOBAL
#define GLOBAL extern
#endif
GLOBAL int myglobal;
GLOBAL int whatever;
//... etc
|
1 2 3 4 5
|
// globals.cpp -- a single cpp file that does nothing but instantiate your globals
#define GLOBAL
#include "globals.h"
// no need to put anything else in this cpp file
|
1 2
|
// all other cpp files
#include "globals.h" // <- they can just #include normally
|
How this works is it hides the extern keyword behind a GLOBAL macro. globals.cpp manually #defines GLOBAL as nothing, which prevents the header from #defining it as extern. The end result is that extern is put there automatically for all files except for globals.cpp. Resulting in the desired effect of having them instantiated once and only once.