when is okay to use global variables

Started by
13 comments, last by amemorex 21 years, 3 months ago
As with many things it isn''t what you do, but how you do it. It isn''t whether you use globals, but how you use them. They should be effectively constants. Write once, read many times. As long as that is true and stays true then you most likely won''t choke on your own "time saving" efforts. If on the other hand you are having to constantly change them before a function and change them back after the call one has to ask just what exactly do you think it better about that than a parameter.
Keys to success: Ability, ambition and opportunity.
Advertisement
quote:Original post by Ronin Magus
What about the object cout? Isn''t that nothing more than just a global object?

"aut viam inveniam aut faciam " - I will either find a way or make one.

MoonStar Projects


Tho it''s in a namespace, it kind of is a global object, and illustrates quite adroitly: an object deserves to be made a global object when its fundamental and unique nature is mandated by the system. There is ALWAYS exactly one cin, one cout, and one cerr, so those deserve to be global.

Don''t listen to me. I''ve had too much coffee.
I guess I might be an "anal-strict" programmer but I''m in good company (if you consider pretty much anyone who is anybody in software development for the last 30 or so years to be good company). Global variables are almost always a sign of bad coding or bad design. Information hiding is universally considered a good coding and design practice – global variables are the exact opposite of information hiding. Reducing variable span and live time is also considered good coding practice – global variables are the opposite of this.

Global variables are bad because they:
* Make code hard to understand (whether it''s another programmer or you in six months).
* Inhibit reuse by making code less modular.
* Make bugs more likely due to lack of access control (ex., an accidental modification can be a nightmare to track down).
* Can have naming collisions -- People who are too lazy to come up with a global-free design are also usually too lazy to come up with names that won''t collide (even worse is the potential of introducing bugs due to accidental reuse of the name).
* Make modifying the code more difficult (to introduce new features, thread safety, etc.).
* Do lots of other bad things (inhibit changes to code and design, inhibit portability, etc.).

Regarding the example of global mouse coordinates, it''s probably bad design in the first place to allow output code (the renderer) direct access to input code (the mouse handler). If you want to swap out mouse input for a keyboard, joystick, or other device, you’ll have to change everything. If you want to swap out your OpenGL renderer for a DirectX or software renderer, you might have to duplicate a ton of game logic that has nothing to do with rendering. If you want to port to a platform that doesn’t send mouse position updates through a message loop but requires an API call, you''d ideally realize the error of your ways and change everything to get rid of the global, but you''d probably just hack in some polling code to update the variable that''ll make things even more nightmarish.

The "convoluted method" I''d propose for helping this in the short term is to simply provide a function for retrieving the coordinates rather than direct access and switch the global variable (which currently has unrestricted external linkage) over to something that hides it (by using either the ''static'' keyword or an anonymous namespace). This simple change will improve your code in a variety of ways. It will be easier to understand because it’s simpler to track down and understand a function GetMousePos versus a variable mousePos. It will lessen the possibility of bugs by limiting modification to only the cpp file that the mouse position variable is declared in. It''ll prevent naming collisions. It''ll make portability simpler because you can simply replace your Win32-specific implementation of GetMousePos with something appropriate for the platform you are porting to. It''ll make it more easily debugged by setting a breakpoint or adding logging inside GetMousePos (versus doing this for every access of the global variable). It could be made threadsafe by wrapping the internals of GetMousePos (and the message handler) in a critical section (might not be a good idea in this specific case due to performance). The long term solution that I''d suggest would be to decouple the input code from the output code.

I have no idea what the design justification for cin, cout, etc. was. My guess would be that it was to provide an easy, portable C++ style output mechanism. You can open an ofstream to "con" under Windows and get similar results to cout but I''m guessing "con" is platform-specific. You can also get similar results by constructing an ostream from a filebuf that''s been constructed from stdout but this would require including a C header (rather than remaining pure C++). If you ever need to modify code that extensively uses cout to use a more generic ostream (such as a file) or to be threadsafe, you''ll quickly understand why indiscriminate use of a global variable is bad. Also, if you ever research some of the implementation specifics of cin, cout, etc., you’ll see some of the hoops they had to jump through to get them working in some cases.

I think that being anal strict is not always good idea.
In fact, you are getting restricted that way, and having some important global variables which is needed in many parts of program is good idea.
as long as threre are only few, it should not be hard to track it. Use search function and verify, if you suspect an error. But you can make it instance of class, which has restricted access for modifying. So what''s wrong with that ? Seems that you want cause more trouble for yourself


-||-
Conscious
FOX
-||-
PRESIDENT OF MYSELF
-||-Conscious FOX-||-PRESIDENT OF MYSELF
Don''t listen to any advice in this matter, infact don''t even listen to my advice. Do what you want to do. If you want to use globals, then use it. Finding ways to avoid simple solutions just because you don''t want globals is placing limitations and slow code into your application. Don''t make things more complicated than they have to be. As for not understanding code in six months. That is what documentation is for dude. Comment your code everywhere. You can never comment too much.
But hey, I told you not to listen to this advice ;-) so now what are you going to do?

This topic is closed to new replies.

Advertisement