Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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.

Global variables are not necessarily bad, just as macros are not necessarily bad, and enriched uranium is not necessarily bad. As long as you make a conscious decision about the pros and cons of a given design choice, you should be all right.

Some of the arguments against global variables are:

  1. They violate good object-oriented design
  2. They make your code difficult to unit-test, since you can not test individual blocks of code without setting up all of the global variables that the code expects to see
  3. They increase coupling in your code: actions in one block of code may affect things in another block of code in unpredictable ways via a shared global variable

Some of the arguents for global variables:

  1. They make it easy to share a single resource between many functions
  2. They can make code easier to read

If, in your design, global variables make sense, and can be used to make your code simpler to read or easier to maintain, without setting yourself up for random errors and testing headaches, then by all means use them.

I write a lot of C code for embedded microcontrollers, and I use global variables all the time. In such a rigid system, global variables make sense. I'm aware of the potential drawbacks, but I have analyzed the pros & cons and I write my code so as to guard against the major pitfalls.

Bottom line: There is no hard and fast rule. Just make the best decision for your particular project or platform, based on the best information that you have.

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

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.

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 `

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.

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.

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.

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.

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.

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top