Ok, so this is a bit of a devils advocate question really.
When are global variables ok, and if never, what would you use as an alternative?
An interesting side-case to this question, how is a public static class field different from a global?
Software Engineering Stack Exchange is a question and answer site for professionals, academics, and students working within the systems development life cycle. It only takes a minute to sign up.
Sign up to join this communityOk, so this is a bit of a devils advocate question really.
When are global variables ok, and if never, what would you use as an alternative?
An interesting side-case to this question, how is a public static class field different from a global?
So far as I know, a public static field is basically a global given that it can be called from anywhere with the exception that it does not clog the namespace.
The only time I personally use 'global' variables in my code are in the form of public static fields that are immutable. In this case there is no need to worry about the value being screwed around by other parts of the program and of course its a lot nicer than having a dozen variables with the same permanent values in each class.
Personally, I use globals for runtime configuration - if a configuration property is loaded at application startup, and only changes infrequently (and only then from one place), it's terrible and error-prone to pass it around to every method that might need to use it at some point. Better off using something that can be brought into scope from anywhere that needs to use it, as that doesn't clutter up and obscure your method signatures and call sites.
CONFIG_
or CFG_
prefix.
Excluding real time/embedded systems, you should only use globals for constant values, really. If you feel that you can't solve your problem without them, you are probably doing something wrong.
Also, look into Singleton pattern, it cold provide a better solution for globals in those situations when you need something to have global access point.
TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOP
is only relevant in the one file / class / section where 'this particular loop' appears.
The problem with global variables is that you need to be aware of them everywhere in your code. However once you've decided that you need to know about a particular global, there is little further lost in using it heavily. Therefore my opinion is that you should have very few global variables, but the few that you have, you should get maximum mileage out of.
For another example of something I feel this way about, look at the use of mixins in Ruby.
It's all about namespaces.
Imagine for a moment that everyone in the world had the same last name. What a mess.
(In India, the Sikhs have all the same last name: Singh --Take a look)
Short version: when it makes it easier to reason about the program. Typically cases are some type of global state or static resource that is widely used.
Long version: Tom Hawtin said "with spooky action at a distance"...that is exactly the problem with globals -- you have to know where it is being used and how, or you can get some really weird and hard to track down bugs. Locals are nothing more or less than a strategy to reduce the scope of what the programmer needs to understand in order to reason about the program.
Another side of the problem with knowing where they are used is that you can end up with duplicate globals -- in which case things can get really weird as most of the programs gets and sets var1 while in a couple of places var2 is used to hold the same information. Particularly when multiple people are working on the same code. IDE's can be helpful with finding usage reducing the cost of globals, but they do nothing for duplicates.
The more globals you have the harder it is to keep track of what is happening with them. They should be few and far between.
The two gotchas with globals and singletons are testability and deployability.
For testing, I've seen too many overly-complex testing harnesses just to deal with poorly planned global and singleton lifetimes. Make sure that any such object has clear and simple start up and tear down rules.
As for deployability, there are two cases to consider. Firstly, how will your global object live? Is it in a static or dynamic library? If that global object gets reused for a plugin, will you get extra copies? Secondly, what happens when that global object is dropped in to a parallel application? Is it thread-safe?
On the whole, I figure those reasons mean that globals and singletons are used only exceptionally.
Development of critical embedded systems usually involves use of global variables.
Stack sizes are tiny, everything is statically allocated (malloc()
is forbidden), global variables are hidden from outside the library they belong to.
In a horrible VB6 code base that abuses globals like there's no tomorrow, I'm guilty of introducing a new one:
Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained
I think it's one of the few valid use cases for a global object.