Sign in to follow this  

Using all global variables?

This topic is 4488 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is using all global variables in my programs a bad practice? It helps me keep track of things easier then having local variables and passing them back and forth.

Share this post


Link to post
Share on other sites
Many people will say its a bad thing since you can easily change them on accident but if you are going for speed over anything, ie programming games, and you can keep track of anything, using globals is better in my opinion, although if you are writing something like an SDK then using globals is clearly a no no since other people wont know exactly what you named your variables in the function.

Share this post


Link to post
Share on other sites
I as well utilize global variables for everything but sometimes I become confused what I am utilizing variables for. If I have the variables localized to something, then I know what that is used for and I won't be able to use that variable for something that I will be in trouble for later.

For example, if I create a global variable called "loop" and used it for all my "for" statements, there is a chance I will have a "for" statement that will execute a function that utilizes the "loop" variable for its own purposes. This will create a headache since instead of the problem being localized to a single part of the application, it might be spread out.

Though, having not type in and return data from my functions is a good things as well since I do not have to fiddle around with passing data in/out of the function.

It mainly will depend on you but if another person were to work on your code, they might not like it at all - even with development documents to look at.

Share this post


Link to post
Share on other sites
I think globals don't help in keeping the code reusable. It's best to put them in their relevant classes (design design!). You could also wrap a global in a singleton. Typical example is a shared logger instance. Also, globals aren't thread safe so you may have to deal with that. If you must use globals then make them static so they're hidden in the compilation unit.

Share this post


Link to post
Share on other sites
Globals are crap.

Seriously, how many variables in your game really need to be global? The same arguments against singletons typically apply to global variables as well.

Does the sound system need to know the game score? Does the rendering system need to know the direction the wind is blowing? Does the input system need access to the Direct3D device pointer? I would think not.

Generally, globals are signals of bad design, and really should be avoided with large projects.

They kill modularity. They also make you really tempted to actually reference the wind direction in the rendering code, which would kill reusability.

In short, try to avoid them. This doesn't mean you need to go OOP to the extreme -- you can still do multi-paradigm programming. Just don't keep all that stuff in the global namespace, because it almost definately doesn't need to be there.

Share this post


Link to post
Share on other sites
Quote:
Original post by DRPhil
Down with global variables. Up with accessor methods.


Down with accessor methods. Up with properly encapsulated code which shouldn't need accessors in the first place because the object's methods define *operations* on the object rather than exposing the data for other functions to manipulate.

Share this post


Link to post
Share on other sites
Quote:

...if you are going for speed over anything, ie programming games, and you can keep track of anything, using globals is better in my opinion...

Premature optimization aside, this may well be wrong. The big reason that comes immediately to mind is your cache. Anything that saves passing a parameter will cost you in terms of cache misses. You also destroy the compiler's ability to perform otherwise trivial optimizations. So you have a questionable optimization coupled with a design that'll hurt in the long run.

Some globals are OK in a 'who cares' sort of sense. You probably won't mind if you have a single Game object that holds passes parameters, for instance. But creating a global enemy object rather than passing an enemy parameter is probably trouble.

CM

Share this post


Link to post
Share on other sites
While I dont think globals are crap, there is after all a place for everything, I dont see a signifigant speed advantage in having all globals, the time it takes to declare a variable on the stack... is marginal, and considering the raw processing power most computers possess today anyways, who cares about that extra nanosecond or two?

Share this post


Link to post
Share on other sites
Quote:
Original post by Deyja
Quote:
globals are better because they increase application speed.
Simply fallacious.

Beyond fallacious, a downright lie - the opposite is true, globals can hinder application speed.

Fixxer, you are hereby charged with being a rumor zombie. Anything you say can and will be ignored in a forum like this [to prevent furhter contamination].

In cases where making a variable global will affect preformance, it will usually do so by hindering it. Let's compare two implementations of a function:

//Version 1:
int i;

void function() {
for ( i = 0 ; i < 10 ; ++i ) {
...
}
}

//Version 2:

void function() {
for ( int i = 0 ; i < 10 ; ++i ) {
...
}
}


So, what's the difference? Version 1 is ugly, and not only that, but i must be stored in memory. "i" can be modified and looked up from any place in the program. In version 2, i is a local variable, which in most circmstances will allow the optimizer to never allocate memory for i, instead using one of the many registers of the processor. Assuming we don't do anything in the loop, the compiler can completely eliminate the loop in function() and remove it. The function will inline into a no-op. Version 1 must at least assign i to 10.

So what's the big deal? Nothing much, until you start accounting for cache misses. If a program forces the OS to load in a 4KB page (possibly from disk if it's been paged out) just because your program writes a variable which is never used anywhere else in the program, that's really bad.



Further, there's no really good reason to use globals in most circumstances. I'd prehaps even argue ALL circumstances. They're brittle in that they limit you to a single instance of that variable - what happens when your program needs to access multiple screens? If you've stored the screen width and height in globals used throughout your program, everything comes tumbling down when they just don't cut the mustard anymore.

If instead you pass things a reference to the screen as needed, all that's needed is to provide the correct screen when you call the function.

Basically, instead of:

int width, height;
void random_render_function( ... ) {
render_square( 0 , 0 , width / 2 , height / 2 );
}
int main () {
GetRandomAPIMetrics( & width , & height );
random_render_function( ... );
}


I do:

struct screen_data {
int width, height;
};

void random_render_function( screen_data & screen , ... ) {
render_square( 0 , 0 , screen.width / 2 , screen.height / 2 );
}

int main () {
screen_data screen;
GetRandomAPIMetrics( & screen.width , & screen.height );
random_render_function( screen , ... );
}


As the program grows more complex, I can retool and relocate things easily:

int main () {
big_huge_screen_manager bhsm;
random_render_function( bhsm.get_default_screen() , ... );
}


Rewiring and relocating data when you depend on global names for access is much harder - they're a hinderance to higher level refactorings.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fixxer
If you can be organized with your code, globals are better because they increase application speed.


Why don't we take a brief tour of the memory subsystem of your computer? A modern personal computer has a hierarchical memory system. The fastest memory is the registers, and then you have two to three levels of cache, which are slower than the registers. Following that is the main memory, and at the bottom is the disk which is used for virtual memory. Now, roughly speaking each level is an order of magnitude slower than the level above it. Following me so far? Now to get better performance we need to keep the working set of memory as small as possible so it fits in the smallest part of the memory hierarchy. If your working set spills out too far then you'll waste a lot of time just waiting for memory to load or store.

Now, roughly speaking, there are a number of different regions in memory that you need to deal with. There's the code segment of your executable which contains the actual machine instructions your program executes, there's the data segments of your executable which is where globals get stored, there's the stack and the heap, and then there are the code and data segments of any dynamic libraries you use as well as kernel memory. Now then, we need to concern ourselves with the tight loop: the ultimate bottleneck of every game. Hopefully in your tight loop you've managed to do away with any system or library calls so all you're concerned about is your executable's data and your executable's code.

Now then, you've got the data on the stack. You're stuck with accessing that since thats where your local variables, return address and what not get put. Now if you're running any sort of non-trivial program you've got some memory on the heap you need to manipulate. And of course, you've got the code you're running. What happens when you throw in a global variable access? Now, you've got a memory reference that is physically non-local to any of the other memory addresses that you need to be working with in this tight loop. This means it takes up a dispropotionately large part of the memory hiearchy, since it won't share a cache line with the stack, code or heap data. The increases the working set. And the real bugger is that the L1 cache for a processor is generally not fully associative, and due to the way that linkers generally lay down the data segments of global variables, the chances are that if you access multiple globals from multiple translation units you're going to get mapped to the same cache line set, which seems likely as your are advocating the use of global variables as a speed "enhancer". This in turn will make it so much more likely that your working set is going to spill out of the L1 into the L2. Or out of the cache and into main memory. This is bad.

Share this post


Link to post
Share on other sites
Loop variables, and variables that are not accessed by any other function, should not be made into globals.

If your working in C, than thats really the just of it.

Else If C++, than you get your Singletons, Accessor Methods, and Encapsulation (I'm just listing whats been mentioned on this post).

Share this post


Link to post
Share on other sites
Quote:
Original post by BKBen7
It helps me keep track of things easier then having local variables and passing them back and forth.


Once you start doing anything non-trivial, you are almost certain to find that the opposite is true.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fixxer
If you can be organized with your code, globals are better because they increase application speed.
Using a global for something that should be a local is not better, it is downright WRONG!
I suggest (nay, insist) that you do your own searching around to find out why.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Another reason against the use of global variable is that the constructor of that variable is called before the main entry point. This means that if an exception is raised during this execution period it will never be caught.

Share this post


Link to post
Share on other sites
Intel C++ compiler does not even allow global variables without prior "extern" declaration. That is very nasty.

What about you have a Singleton, someone has to create at least one instance?!

test.h:

class CTest : public mySingleton<CTest>
{
public:
CTest() {...}

void DoSomething(...)
}

test.cpp:

static CTest myTestInstance;

The problem here is, that without static it does not work. When I use a singleton in some kind of static library, i can not say: CTest::GetInstance()->DoSomething since no instance of CTest does exist. If I use Statitc the compiler does not complain anymore, but why does static set him allright?

Share this post


Link to post
Share on other sites
Intel C++ compiler does not even allow global variables without prior "extern" declaration. That is very nasty.

What about you have a Singleton, someone has to create at least one instance?!

test.h:

class CTest : public mySingleton<CTest>
{
public:
CTest() {...}

void DoSomething(...)
}

test.cpp:

static CTest myTestInstance;

The problem here is, that without static it does not work. When I use a singleton in some kind of static library, i can not say: CTest::GetInstance()->DoSomething since no instance of CTest does exist. If I use Statitc the compiler does not complain anymore, but why does static set him allright?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Is using all global variables in my programs a bad practice?

That depends on the use. Generally, there are better ways, as described above. Some times, they are unavoidable because they are systematically used is many places and it impacts performance otherwise. An example is to set function pointers to OpenGL extension functions. Not sure how encapsulation, accessor methods or singletons could be of any help here.

Share this post


Link to post
Share on other sites
the most used method is to keep variables as local as possible
and to use pointers on all large variables so that when you do a function call (example)

HBITMAP bmp; (large memory hogging structure)

somefunct(bmp); //the entire HBITMAP will be copied into the stack for somefunct, bad very bad

somefunct(&bmp); //only a 32 bit (or 64 bit) pointer will be copied instead of a multimegabyte HBITMAP

when it comes down to it using a structure of pointers for variables that must remain global works faster for large global variables, since the actual data will not be accessed until you actually use the data the pointer is pointing to, then there will be the slow process of getting that data from outside of the local functions stack

remeber kiddies..pointers are our friends..globals are bad

Share this post


Link to post
Share on other sites
Quote:
Original post by Samurai Jack
Intel C++ compiler does not even allow global variables without prior "extern" declaration. That is very nasty.

What about you have a Singleton, someone has to create at least one instance?!

...code snip...

That is not a singleton. Your constructor is public.

Quote:
Original post by Samurai Jack
The problem here is, that without static it does not work. When I use a singleton in some kind of static library, i can not say: CTest::GetInstance()->DoSomething since no instance of CTest does exist. If I use Statitc the compiler does not complain anymore, but why does static set him allright?

For a correct Singleton, no one declares an instance except the class itself.

Share this post


Link to post
Share on other sites

This topic is 4488 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this