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...