views:

1285

answers:

13

Most of the objections I see to using global variables make sense since they refer to issues of multiple threads, thread safety, etc.

But in a small, single threaded, non-OS, case, what objections do you have? In my case, I'm writing my embedded system in "C", if it matters. I'm also the only developer on the product.

Why would eliminating global variables make my code better?

(After reading several responses, I realize I also should have pointed out that this system has no dynamic memory allocation (e.g. malloc). All the memory is statically allocated at compile time.)

+7  A: 

Because it minimizes coupling. Your system may be small now but if you keep on working, it may turn out not to be.

Otávio Décio
This is the point I wanted to make. Just because it's small and single threaded now doesn't mean it will always be.
rampion
rampion: missing the point, which is decoupling for reusability, not thread safety.
A: 

With global variables it's often hard to know where or when they are updated and what piece of code updates that variable. There is no control as to who can update it or in what way the variable is updated.

It's not that hard to keep track of if your application is small - but the larger your application becomes, and the more global variables you have, the more the application code looks like spaghetti.

In short - it becomes a maintenance and debugging nightmare.

rein
Why is that not true with pointers? If I have a variable that's passed by pointer to another function, it isn't always easy to see where its value was changed.
Nathan Fellman
A: 

The problem is tracking down which bit of your last code modified the state of the global. Generally, you want to keep variables within the smallest possible scope so that you can more easily reason about them.

Richard
A: 

One reason that comes to mind is future proofing. You might be the only developer on your product now, but it's conceivable others will maintain it later. Of course this might not be true in your particular case.

While your product might be small and tidy right now -- where using global variables doesn't complicate the overall design or compromise readability -- whose to say the product will not become much larger or be incorporated into another product? And god forbid another maintainer/developer come along have to sort out your use of global variables.

Of course, you could decide to use global variables now and when the project appears to be getting more complex go back and rewrite portions of it, but why force that extra work on yourself? You're more likely (if you remember the global vars at all) to decide doing that work is too much effort, and let the design go: at this point you are in trouble!

So, save yourself the headache and design with your eye on the future. The work required now will probably make life easier in the future.

If that didn't convince you, imagine being the developers who worked on this project, and had their code found faulty and guilty of bad programming practices in front of the Supreme Court: Buggy breathalyzer code reflects importance of source review

Casey
+11  A: 

It wouldn't.

The two fundamental issues with global variables is simply cluttering the namespace, and the fact that "no one" has "control" over them (thus the potential collisions and conflict with multiple threads).

The "globals are bad", like pretty much every other computer programming idiom is a guideline, not a hard and fast rule. When these kinds of "rules" are made, its best rather than simply adopting the rule by rote to understand the circumstances and motivations behind the creation of the rule. Don't just take them blindly.

In your case, you seem to understand the nature of your system and the arguments around the rule and decided that it doesn't apply in this case. You're right, it doesn't.

So, don't worry about it.

Will Hartung
I appreciate the many comments and answers. I selected this as my answer because it most clearly summarizes my rationale. I do feel 'funny' choosing an answer that validates my design choices, but hey, I guess I will anyway.
loneRanger
A: 

Keeping most variables local and reducing their scope helps promote better programming practices. It also reduces the risk of mistakenly changing a variable and having to trace through functions looking for unintended or non-obvious consequences. I believe it also makes the code easier to read and maintain since most of the variables relevant to a particular section of code are defined and initialized nearby. Otherwise I seem to be constantly referring back to the section of code defining all the golbals. I do use some globals, but mainly for passing configuration information down to sub modules.

jholl
+1  A: 

The short answer is that global variables have historically been the source of subtle bugs. But then (putting on my functional programmer hat) all variables have been sources of subtle bugs.

Basically, a global variable means that you can't look at a piece of code using the variable's value, and know what it's going to do without knowing what every other piece of code setting that variable's value has done in the past.

Charlie Martin
+11  A: 

Here is a good article that gives reason Why global variables are Bad

Why Global Variables Should Be Avoided When Unnecessary?

Non-locality -- Source code is easiest to understand when the scope of its individual elements are limited. Global variables can be read or modified by any part of the program, making it difficult to remember or reason about every possible use. No Access Control or Constraint Checking -- A global variable can be get or set by any part of the program, and any rules regarding its use can be easily broken or forgotten.

Implicit coupling -- A program with many global variables often has tight couplings between some of those variables, and couplings between variables and functions. Grouping coupled items into cohesive units usually leads to better programs.

Memory allocation issues -- Some environments have memory allocation schemes that make allocation of globals tricky. This is especially true in languages where "constructors" have side-effects other than allocation (because, in that case, you can express unsafe situations where two globals mutually depend on one another). Also, when dynamically linking modules, it can be unclear whether different libraries have their own instances of globals or whether the globals are shared.

Testing and Confinement - source that utilizes globals is somewhat more difficult to test because one cannot readily set up a 'clean' environment between runs. More generally, source that utilizes global services of any sort that aren't explicitly provided to that source is difficult to test for the same reason.

Adding globals is really easy. It's easy to get in the habit of declaring them. It is much faster than thinking of a good design.

Global variables are not as bad as you may think, they just should be avoided whenever unnecessary. Global variables can have good use for a variable that would be used thoughout the program,making sure you keep in mind that you always have to keep track of where that variable takes changes; but for variables that tend to be only used within limited parts of the program is good reason to avoid having it global.

TStamper
Global values can be only be seen by modules that include the module that they are defined in.Following that logic one could outlaw public and protected fields because everybody can gain access to them by inheriting.
Marco van de Voort
+8  A: 
e.James
Agreed. Like so many "rules" in software (especially C), there are times when the situation requires that they be bent or broken. I try to avoid globals as much as possible, but there are a small number of occasions when they are the best solution to a problem.
Steve Melnikoff
global variables can make the code more difficult to read aswell... and IMO thats more likely.
smerlin
+2  A: 

It is a matter of scope. We have developers that love to make global variables to do local concepts. It make the usage of these variables much harder to keep track of, so it is easier to make mistakes in the use of them.

You can keep your wallet on your front porch also, but then you have far less control over who is accessing it.

That being said there are some valid uses for Global variable, but like any other rule worth following. This is the exception not the normal case. Their very existing points out that they have a use.

If you do decide to use a global variable try to comment them well and give them good names. It really bothers me when people make global variables like "bool bIsFound;"

We make it a point to evaluate each new global variable in code review and see if there is a better approach.

John Christman
+1  A: 

Perhaps global variables aren't bad in your case. On the other hand, do you need them? What do you gain by using them?

Even in your case, global variables make it harder to figure out the state of the application. That may hinder debugging, and it may lead to subtle bugs.

Global variables also make testing harder. They add dependencies on external code that you may wish to avoid during testing.

But finally, globals are hard to avoid when programming in C. In a more advanced language, globals are simply pointless most of the time. Using them just doesn't make your code any clearer.

In C, there are plenty of cases where globals are just the best, simplest and cleanest solution.

So in your case, take it on a case by case basis. You'll probably end up having some globals, but don't make a variable global unless you're sure it's actually the best solution, not just now, but also a year from now when you have to debug the code or make the application multithreaded.

jalf
+3  A: 

Global variables are necessary in a small embedded application written in C. For example, you need to use a global variable in order to pass information between an Interrupt Service Routine and another module. These are some tips, that will help you make effective use of global variables in embedded applications:

  • Make a distinction between static variables and global variables. Static variables can be used from all functions in the same C file. They are the equivalent of private members in a C++ class. In C you have to do the compiler's job yourself. Use the static keyword to avoid accidental use of the variable outside of the module and make evident its scope. You may want to prefix the variable with the module's name.

  • Follow a naming convention for global variables (used by many C files). Make it clearly evident that they are global.

  • If you need a lot of global variables, consider bundling them in a struct.

  • Use the volatile keyword, when necessary. This is needed if a global variable is modified by an ISR.

kgiannakakis
+1  A: 

Code which uses global variables is harder to maintain. Since the maintainer must find every use of thevariable in the system before she can know precisely what the variable does. Since this slows maintainence it should be avoided as much as possible. That's it `