Sign in to follow this  
Sillencer

Global Variables

Recommended Posts

Sillencer    171
If I have some variables, that are used often, like pointer to graphic context, Display Window, resources reference, is ok to put all these inside a header file and include it in a precompiled header ?

Share this post


Link to post
Share on other sites
yewbie    677
I used a class to store all of my global variables and I can just pass a pointer to that class to anywhere I need to access that data.

Share this post


Link to post
Share on other sites
Sillencer    171
[quote name='kunos' timestamp='1311618731' post='4840106']


ya I think you'll live :D
[/quote]

what do you mean ? It's a really bad idea ? another way to do this ?

Share this post


Link to post
Share on other sites
ApochPiQ    23003
Well, nobody's going to come to your house and punch you in the face for using globals, but that doesn't mean you won't regret it at some point.

Some details on your code would be nice, so we can suggest specific alternatives.

Share this post


Link to post
Share on other sites
Serapth    6671
Globals are very often problematic to design and can make maintenance a nightmare, but that said, they aren't always evil. Eventually someone is going to come in and suggest a Singleton, which sounds like a great idea but is generally just a global by a different name. As ApochPiQ said though, without further details... who knows.

Share this post


Link to post
Share on other sites
frob    44904
There are many objects in a game that you only generally want one of within your game, and you need frequent access from multiple sources. Those are great candidates to for global access.

The problem is not that globally accessible objects are inherently bad. They happen all the time, and there are many good reasons for them.

The difficulty is using them such that they are always in a good state. You will need to consider how you intend to use them, and take steps to ensure you limit access to a way that integrates well with your design. If they can become invalid then obviously it is a problem. If it does not work well with your design then it is a problem.

Share this post


Link to post
Share on other sites
Sillencer    171
I use ClanLib SDK.... Every entity object has CL_Sprite object that contains entity animation.... to create a CL_Sprite object i need to pass as parameters: GraphicContext, resources reference, and finally a string with the sprite name...

[code]this->sprite = CL_Sprite(gc, name, &resources)[/code]

So for every entity I need to pass 3 parameters , and this is just a base class... And I'd like to reduce this to just one parameter: a string which contains the sprite name...

Was thinking maybe about a SpriteManager class, so I could pass the string, and it would return a CL_Sprite object...

But I'm not sure what is the best way. Am I going the wrong way ?

Share this post


Link to post
Share on other sites
Serapth    6671
[quote name='Sillencer' timestamp='1311621129' post='4840135']
I use ClanLib SDK.... Every entity object has CL_Sprite object that contains entity animation.... to create a CL_Sprite object i need to pass as parameters: GraphicContext, resources reference, and finally a string with the sprite name...

[code]this->sprite = CL_Sprite(gc, name, &resources)[/code]

So for every entity I need to pass 3 parameters , and this is just a base class... And I'd like to reduce this to just one parameter: a string which contains the sprite name...

Was thinking maybe about a SpriteManager class, so I could pass the string, and it would return a CL_Sprite object...

But I'm not sure what is the best way. Am I going the wrong way ?


[/quote]

A SpriteManager of sorts is most likely exactly what you want to do. From your example, I don't see your global use. If you are looking at storing name, resources or gc as a global, the answer is an emphatic, no to all of the above.



You however have come to your own answer, the SpriteManager and perhaps a GraphicsManager class as well ( that SpriteManager calls to get the context in the first place ). That said, it seems a bit like bad design that a sprite is so closely coupled to a GraphicsContext in the first place, but obviously thats not your library and there isn't much you can do about.



TL;DR, yes, make a SpriteManager class.

Share this post


Link to post
Share on other sites
Dragonion    131
[quote name='Sillencer' timestamp='1311618529' post='4840105']If I have some variables, that are used often, like pointer to graphic context, Display Window, resources reference, is ok to put all these inside a header file and include it in a precompiled header ?[/quote]
In general, global variables could/should be used in these situations:

1. Constant values[code]static int const GAME_VERSION = 0x00000000;[/code]
2. Values that are initialized once and don't change while the program is running[code]static HINSTANCE inst; // initialized once at the beginning of the program[/code]
Variables that may be read/accessed in several different sections of the code but only changed/updated in one (like the screen resolution) [i]could[/i] be declared global, but if you do so make sure your program architecture ensures that these sections are not executed simultaneously.

Share this post


Link to post
Share on other sites
Hodgman    51223
There's only a few reasons to use a global:

1) You're lazy and can't figure out a better design [i]yet[/i].

2) Constants.

3) You're in a situation where you absolutely have no alternative but to use a global. Which is exactly almost never.

You currently fall under case #1. Laziness is ok sometimes if you don't care about people looking over your shoulder and chastising your lack of perfection. Just roll with it. You're not going to be holding this code up on a pedestal 2 years from now, marveling at it's perfection, so just go with your gut and learn from it later.

Share this post


Link to post
Share on other sites
frob    44904
[quote name='Hodgman' timestamp='1311676194' post='4840443']
There's only a few reasons to use a global:

1) You're lazy and can't figure out a better design [i]yet[/i].
2) Constants.
3) You're in a situation where you absolutely have no alternative but to use a global. Which is exactly almost never.

You currently fall under case #1. Laziness is ok sometimes if you don't care about people looking over your shoulder and chastising your lack of perfection. Just roll with it. You're not going to be holding this code up on a pedestal 2 years from now, marveling at it's perfection, so just go with your gut and learn from it later.
[/quote]

That is an amazingly elitist statement.


Many things are global for good reason.

There is a global memory allocator, provided by the system. You can provide more narrowly-scoped versions, but there is a global one that is created for you by the system. Would you remove it from the language? How would you replace it?


There are global IO streams, provided by the system. You do not need to use them, but they are present for all takers. There is a globally used locale object. Would you remove them, and require every program that performs even the most simple I/O to construct locale objects, and have every stream get imbuded with this custom object?

Calls to kernel control, hardware control, iocontrol, and other system settings are global settings. Any thing with scope bigger than just your program is effectively global to your program. Good luck removing them.

Many programs will create a general purpose logger and create a global instance for general use. Many programs will create per-frame performance data and update information, and make it available globally for general use to any system that needs to know. Many programs will have a global object with pointers to various systems and managers since those systems truly need to be known and used across the program.

Many times a class will have need of a general purpose object that specifies behavior that can be shared but can also be replaced if necessary. Such a shared object can often be best implemented as a global object.




Yes, when used incorrectly global objects will increase code complexity and module interdependence. Don't do that.

However, used properly, global variables can dramatically reduce code complexity. That's when you use them.


A hammer is a tool that when used incorrectly can cause serious problems. But used correctly it is a great tool.
Fire is a tool that when used incorrectly can cause serious problems. But used correctly it is a great tool.
Surgery is a tool that when used incorrectly can cause serious problems. But used correctly it is a great tool.
Dynamite is a tool that when used incorrectly can cause serious problems. But used correctly it is a great tool.

Similarly, so it is with global objects.



Yes, there are many reasons to not use globals. Globals lose locality controls, and they can have issues with access control and constraint checking (although they don't have to if designed properly). Globals can have concurrency issues, and they can introduce some issues for testing. Used improperly they suffer from side effects. Indiscriminate access to a global variable can seem to show very odd functionality, but this is always true: if you start mucking around with the stdout stream and changing its properties you can expect problems from anyone using the stdout. If you start mucking around with the global locale you can expect all your streams changed based on the locale settings. The problem isn't the existence of the global object, the problem is the misuse of the object. The answer is simple: Don't do that.

However.... Globals are great when they represent things that truly are available everywhere in the program.


If that is the case, and a global variable is the answer to your problem, don't force your code into a solution that doesn't fit.

If the right solution is a global variable then use it without guilt.

Share this post


Link to post
Share on other sites
Hodgman    51223
[quote name='frob' timestamp='1311704921' post='4840720']That is an amazingly elitist statement.[/quote]I'd prefer "facetious" ([i]I wasn't using the mathematical definition of [url="http://en.wikipedia.org/wiki/Almost_surely#cite_ref-Gradel_0-0"]almost never[/url][/i]), but feel free to get up in arms and write a page-long retort if you like.

[quote]There is a global memory allocator, provided by the system.[/quote]And using it is a bad idea born out of laziness [img]http://public.gamedev.net/public/style_emoticons/default/laugh.gif[/img]

Share this post


Link to post
Share on other sites
szecs    2990
I agree with Dragonion. If a variable is initialized once at startup then never-to-be-changed again (these are so obvious, only idiots would try to alter them, and you can't make a code idiot-proof anyway) and a lot of stuff uses (reads!) them, I'd use globals instead of passing around all the shit just to avoid using globals. The hInstance and hWnd of the main window can be examples in most cases. Of course, you can dump everything in a struct and pass it around, but I really see no point in passing it around.

Of course, use strict rules, good naming, etc.

Disclaimer: I'm a tinker and I work alone. And my knowledge is so poor, that I was never able to produce sane code without globals. Especially when making tools/editors with lots of overlapping states.

Share this post


Link to post
Share on other sites

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