The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Is my use of global variables bad programming practice?

When I'm writing procedural code, like a small C program for example, I usually have anywhere from several to a dozen global variables declared towards the top. I don't declare just anything to be global, only variables that are used throughout the program (ie accessed by lots of functions) and that persist throughout the life of the program. I do it as a convenience, so I don't have to pass the same variables over and over again to many function.

My question is, Is this bad programming practice? The consensus seems to be that you should almost never use global variables. But in the example I gave, what's the alternative? Putting the global data in locally scoped struct and passing around pointers/references to that instead? What do you gain by doing this?

Wednesday, October 04, 2006
for example, what's up there?
Wednesday, October 04, 2006
In my opinion this is just fine in small programs, by small I think of a program that consists of one source file.

Just look at the source for many of the unix tools we use every day, they make use of globals and work just fine :)

When your program is large enough to require some design and multiple files, then globals can become hard to manage/track.
Jason Send private email
Wednesday, October 04, 2006
> Just look at the source for many of the unix tools we
> use every day, they make use of globals and work just fine

They work fine but they don't read fine. Try finding bugs in these suckers and you soon get sick of the globals everywhere policy.
son of parnas
Wednesday, October 04, 2006
You might want to pick up Fowler's "Refactoring" and try techniques such as "Replace temp with query".
Wednesday, October 04, 2006
This really depends on how its done. If you are passing parameters through globals, that's what we are really talking about when we speak of the dangers of globals.

If you have a 1000 line file and some variables used only in that file and they are declared static, I'd call them 'modular' variables and not global at all.
Meghraj Reddy
Wednesday, October 04, 2006
Can you put them in a struct, it's a bit safer?
A single 'state' struct that stores command line options, or configuration settings is probably fine - having it global is neater than passing it through every function just because some message box needs to know if quiet mode is on.
Martin Send private email
Wednesday, October 04, 2006
I *hate* globals.
I *hate* classes with 20 object variables and with 50 private instance methods using those object variables deep down obscure call chains.
I *hate* globals.
Wednesday, October 04, 2006
Global variables have their place, but they should not be over used. Generally speaking you should aim to pass any variables that a function *regularly* needs as an argument on the function call. If you pass absolutely everything as an argument then you may end up with an extremely lo-o-o-o-ong list of arguments. If there is a set of variables that *may* be referenced within any function in the system then IMHO it is OK to leave those as global variables so that they can be accessed as and when necessary. Note that it is better that these global variables have their values set just the once and then read fom then on. If you find yourself updating the same global variable time and time again then you should really include this as an argument on each function call. It can be a real debugging nightmare when a global variable keeps having its value changed and you don't know where this is happening.
Tony Marston Send private email
Wednesday, October 04, 2006
Just think about multiple threads and global variables.
You probably don't want that!

Also, by using globals, you make reuse of your code awkward. It's hard to reuse functions if they rely on globals for half of their functionality. Also, this causes functions to have side-effects, which is hardly ever desirable.

To reduce the number of parameters for your functions, just declare a struct (C) or a class (C++) at the start of your program, and pass its address or its reference around.

That makes it also a lot easier if you want 'two instances of something'. Just declare two of those structs.

Good luck.
David Send private email
Wednesday, October 04, 2006
I don't think it's bad, so long as:

* You know the difference between short-lived and long-lived variables: don't use a (long-lived) global variable when a short-lived (stack) variable would do instead

* It is a small program

When I'm writing a small program, I usually declare a small class which I instantiate from main. The data that's defined as members of tht class is accessible from every function member in that class: they act as 'global' (within the class) variables.
Christopher Wells Send private email
Wednesday, October 04, 2006
"But in the example I gave, what's the alternative? Putting the global data in locally scoped struct and passing around pointers/references to that instead? What do you gain by doing this?"

Thread/reentrance safety. You might think your program will never use threads, but one day one of your functions will call itself and you will be hosed.
Wednesday, October 04, 2006
My (least) favorite thing is a member variable in a class that is essentially just used as a working/temp variable in a method, but holds no other useful state.  This is tantamount to a global variable as well.

But if the program fits on a few pages, who cares?
Meganonymous Rex Send private email
Wednesday, October 04, 2006
If you are using globals ONLY to avoid passing parameters to all the functions that use those values, then you are probably engaging in a bad practice. Passing values as parameters to functions allows the function to be reused in another context with minimal fuss and bother. These other contexts may even be within the same program (if, for instance, you added multiple threads to a previously single-threaded program) or you may extract the function from its original context for use in a new program. You may not feel the pain of global variable right now, or in a small program, but if you work on a large project that has a long maintenance period, you WILL regret the use of global variables.
Jeff Dutky Send private email
Wednesday, October 04, 2006
There's almost never a good excuse for using global variables.  This is one of those things that separates the true software developer from the guy who just sits around hacking away without understanding the consequences of what he's doing on a deeper level.  It's semi-excusable in small throw-away programs but if you're used to never using globals, you probably won't use them in small throw-aways either. 

Honestly, if you need to pass that many arguments around, there's probably something wrong with your function design.  It's rare for a properly designed function to need a large number of parameters.  A function should do one thing and do it well and this usually limits the needed parameters.  When you do really need that many parameters, the struct approach that others have mentioned is good.
SomeBody Send private email
Wednesday, October 04, 2006
1. you have a vision of what you want to make
2. you model the solution in your head
3. you represent your solution using code

Try to make 3 match 2.  If the concept in 2 is global than the code in the representation should be global

Lots of people say that variables should not be global
Plenty of people say that functions should not be global
I've never heard anyone say that types should not be global

As far as I'm concerned they are all the same.
Tom C
Wednesday, October 04, 2006
I have a convention where global variables are prefaced with a lower case g. For example gNumUsers. However it is probably still nicer to use getter and setter functions to encapsulate access to global  variables (this may impact on performance slightly though). Some key questions are as follows: Is the code readable and maintainable using global variables? Is it clear where and when the value of the global variable is updated (in general it is best to have one writer and many readers). Are there any potential thread safety issues? What will be the impact if the type of the global variable needs to change i.e. from a short to an integer? Is there any logical grouping of global variables that is better expressed in a struct? (It is also easier to pass around a pointer to a struct than it is to keep passing the same 3 variables as parameters into every function call). Are there any conventions that need to be followed when the global variable is written to? Is there any defensive programming (i.e. range checking) that could be done when the global variable is updated?
Colin Sanson Send private email
Wednesday, October 04, 2006
I agree 100% with SomeBody; it may be pedantic, but I don't think it is even a good idea in small personal apps - that can start a really bad habit. Over time, hopefully one gets used to not using them at all and more importantly doesn't even think of using them unless there is some wierd situation where it is required :D.
Thursday, October 05, 2006
Never use global variables. That is, unless you have a very good reason. Seriously, as a rule you should avoid globals but there are some situatioins where it may make sense. In embedded systems you will see them fairly frequently. I second the previous poster who said that you should not use them in small, personal projects. If the app is small you should be able to reason a way around them pretty easily. And, like they said (them or someone else), once you start it's hard to stop.

Remember kids: guns don't kill people, global variable do.
A. Nonymous
Thursday, October 05, 2006
The advantage of passing 'structs' around is that you can explicitly see in the call what data structures are affected by that call.  When a call affects a global, you just have to "know" that is happening, or document it in the comments in some way.

When you come back to your program in the future, you may not just "know" anymore what globals are affected where.  So to make any modifications, you'll have to re-read the entire program to make SURE you understand the 'global' side-effects of each call.

It's also much easier to re-use code that DOESN'T use globals.

Now, having said that, some things ARE global.  In Unix, the FileTable is global.  The command line parameters start out global.  The 'err' library variables are global.

So, that's why they are sometimes necessary, and why your use of them should be as little as possible.
Thursday, October 05, 2006
I try to steer clear of using global variables unless it is absolutely necessary!

My God, each global variable you use significantly increases its scope which means there are more things that can go wrong.

Your cyclomatic complexity has a tendency of rising as well.

Some devs write code to refactor later. I refactor code as I write it taking cyclomatic complexity into consideration.

I have been known to use GV but when I do, I take a SPECIAL amount of EXTRA time in testing them to ensure that the scope of those variables are correctly handled pursuant to their implementation.
Brice Richard Send private email
Friday, October 06, 2006
In the firmware world, often local variables consume stack and globals are allocated elsewhere. 

So it pays to balance things: it's usually better to deal with the architectural and design issues associated with globals than the freakish and hard to debug issues associated with stack corruption due to large local variable memory requirements.
rkj Send private email
Monday, October 09, 2006
I'll add my vote to the pile.

Don't use global variables *except* for constant static plain-old-data - for example, a table of Unicode character attributes, which is the sort of thing that crops up a lot in my work.

If a value is changeable it shouldn't be global. I've followed that rule for many years now, and I'm sure it has saved me thousands of hours of lost time tracking down bugs - and eventually being forced to refactor to get rid of the global variables, which is what I used to do before I realised (duh) that it was better not to have them in the firts place.
Graham Asher Send private email
Tuesday, October 10, 2006
A dozen or less globals in a small program that only you have access to the source code? Don't sweat it, it's fine.
Anthony Dunleavy Send private email
Friday, October 13, 2006
Code that uses nonconstant global variables is Detestable (hard/impossible to dest, see Martin Fowler).
Wouter Lievens Send private email
Wednesday, October 18, 2006

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz