never use globals?

Sep 20, 2008 at 10:55am
I was reading some old threads about extern keyword and found "never use globals, unless their constant".
http://www.cplusplus.com/forum/beginner/2079/
I dont understand whats wrong with globals and how to avoid them. Should I put them into some class?
Sep 20, 2008 at 12:43pm
The problem is that globals are a breach in the structure. Abusing them leads always to problems. Here's an example (http://rinkworks.com/stupid/cs_programming.shtml ):

I was asked about taking on a contract to maintain a piece of software. Something about the way it was presented made me wary. I asked to look over it first. What a sight! I use it as an example of why not to use global variables. Among other things, there were files with suites of functions on the following order:

adjust_alpha()
{
alpha = gamma + offset * 3;
}

adjust_beta()
{
beta = gamma + offset * 3;
}

Dozens of functions that differed only by the global variable they modified. Just picture it: a multi-thousand line program with a graphical interface and a database that never used function parameters.

The original programmer painted himself into a corner with his variable names. Clearly if you need variables "up," "down," "left," and "right," you name them as such. When he found himself needing those direction names in different parts of his program but was stuck because global variable names had to be unique, his solution was to use names like:

up, _up, up_, Up, uP, UP, _Up, _UP
down, _down, down_, Down, dOWN, DOWN, _Down, _DOWN

...and so on. Even the densest of my students comprehended immediately why that was bad. Needless to say, I turned down the job.

There are moments when using globals is acceptable. For example, when putting together a dirty solution and are too lazy to do the proper design, so you use globals instead of passing certain parameters to all functions.
Also, when there are parameters that are required all over the program, and the program has many (MANY) functions, or if you need a new parameter in a function that is so deep in the call stack that adding it would require a ridiculous amount of editing compared to how many times this parameter is used.

Use your discretion, but keep globals as a last resort.
Sep 20, 2008 at 3:51pm
Great link! The one that really had me laughing is:
/* Return code=1: generic error condition
Return code=2: all other error conditions */



However, past that, I should say unequivocally that

there is nothing wrong with using globals as long as it isn't gratuitously.

By that I mean that global variables have their place just as any other structure, and should not be used to keep non-global state. Just as you wouldn't use a local variable to store global data, don't use a global variable to store local data.

Knowing the difference between the two is part of being a (competent) programmer.

As an amusing image to 'drive' the point: I could park my car in my bedroom, and it would work just fine that way (I've a nice, wide screen door into the backyard), but it sure would be better in the garage; it wouldn't tempt me to go to work without getting cleaned and dressed, and I wouldn't use the back seats as a bookshelf, and it wouldn't leave grease spots on my nice, red carpet.

C++ is a multi-paradigm language, meaning it can be used procedurally, object-orientedly, or functionally, or any combination thereof.

But what people forget is that no matter what programming paradigm you use, the program's internal environment is the same. There are global resources and there are local resources. You have to know the difference. Paradigm only organizes those resources.

Good examples of global resources (from the program's point of view) are:
- program options
- input and output devices and services
- OS services
- IPC structures
- shared thread data and status
- shared code (for example, code in DLLs)

Good examples of things that should be local are:
- subprocess parameters and results (aka: function arguments and return values)
- user responses (things like cin >> something;)
- program state (do I need to redraw? quit? calculate x or y? etc)

Often enough there is overlap between the two categories, and some judicious choice must be made as to how to treat an objective.


Whenever you read someone spouting something like "Never do X" or "Always do Y" there should be two or three red flags popping up in the back of your head. More often than not you can take such advice with a (fairly large) grain of salt. Always/Never rules are excuses to avoid thinking.

http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15
http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.16
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.2

Personally, I tend to mark said person(s) down as someone generally safe to ignore --because he is too presumptuous to trust with good, usable advice.


'Pure' functional languages try to make the decision for you. Haskell, for example, doesn't allow access to any global resource unless you can work your head around monads (a special kind of transcendent call-with-continuation --essentially a viral, globally bound local, IMHO). Mathematically this is great. But in real life, Haskell can only be run in a box. Imagine how fun it is to have someone visit with a little black box that he only opens occasionally to see what new thing is inside of it. It is rather boring unless you know something about the box.

To amend helios's words just a little:
The problem is that globals can be used to breach ... the structure.
Using them to accomplish such breaches is the abuse that will lead to problems. But using them for their proper purpose: as a global resource, is not a breach or abuse.


Sorry for the long-winded response. My body and brain aren't working full-speed today...
Last edited on Sep 20, 2008 at 3:53pm
Sep 20, 2008 at 4:13pm
Ah, yes. That's actually what I tried to say. They are a breach in the structure when... Well, when they breach the structure.

So you mean I can stop feeling guilty about making my command line options structure global?

I'm glad you liked the link. You probably know about http://thedailywtf.com/Default.aspx already, but I'll post it here, anyway. My favorite section is Error'd.
Sep 21, 2008 at 1:10am
:-)

Yeah, I knew that was what you were saying, but I've learned that I have to say the same thing three or four times --differently each time-- for the right idea to sink in.

I actually don't spend that much time online looking through news/humor/hacker/IT/etc tribunes.

Except for options that control, essentially, which sub-program is run, I almost always keep a global structure that handles them. Preferrably a class, since creation can cause things to be initialized in the following order: defaults --> registry --> command-line options; as appropriate.
Sep 21, 2008 at 7:49pm
I dont understand whats wrong with globals and how to avoid them. Should I put them into some class?


Generally, you should never use a global variable because you cannot encapsulate it. So it breaks one of the fundamentals of object orientated development. This is important when working with a team of developers. It's a good development technique to help prevent other developers from introducing bugs when working with your code.

In OO, using a global variable is usually indicative of bad design. In C or Non-OO C++ there is no problem using globals. I speak only from a pure-OO design philosophy.

Topic archived. No new replies allowed.