272

In C/C++, are global variables as bad as my professor thinks they are?

GEOCHET
  • 20,623
  • 15
  • 71
  • 98
  • 17
    I'll bite in case he's trying to tell a joke... "how bad are they"? – Zach Scrivena Jan 27 '09 at 18:38
  • http://stackoverflow.com/questions/357187/global-variables-when-are-they-acceptable – mmcdole Jan 27 '09 at 18:46
  • 14
    I think that this question was pretty interesting! Software development is still facing the same old pitfalls since the beginning and programmers often still don't know that using global variables, gotos, short named variable IS NOT the problem. Bad code is written every day without using them. +1 – Sylvain Rodrigue Jan 27 '09 at 19:11
  • 76
    How can we possibly answer? He hasn't told us how bad his professor thinks they are. :) – Steve Fallows Jan 27 '09 at 21:39
  • 1
    @Sylvain I 100% disagree. Using global variables add dependencies to the environment, so you can't easily test modules. It makes it hard to debug because you never know who's reading and who's writing to the variable. Global name collisions are also a problem. Don't even get me started on singletons, there are cases when they are valid (when they don't hold state), any other use of Singletons is a euphemism for global variables. `singletons are for simpletons` who don't don't want to organize their code properly and restrict data access :). Bad code goes in every day, and globals make it worse – Juan Mendes Dec 28 '12 at 21:26
  • 9
    @Juan Mendes I 100% agree with you! The problem I was talking about is that many developers know that they should not use global variables but they just DON'T know why! And thus I have seen many large softwares where each and every functions received the same mega-structure containing +100 fields - Look mom, no global variables! Same problem as so called "good practices": they are good practices in SOME contexts, not in all context. Using them MAY create unmaintenable code. Cheers. – Sylvain Rodrigue Mar 18 '13 at 09:30
  • 2
    Not an answer, but globals are fine for something like a `verbose_flag` that is set in `main` and never ever written again. – Miles Rout Jun 17 '14 at 12:17
  • 3
    There are very few good uses for global variables. One possible, but debatable use, would be a global "configuration" object, that reads in a config file once at startup. – Siler Jul 31 '14 at 15:44
  • I always thought that they are bad because they prevent the compiler from compile time optimization. – MimSaad Aug 21 '17 at 15:44
  • If using Global state is wrong, then using databases is wrong, as that's what they are global state. – Muhammad Umer Dec 08 '20 at 04:36
  • @MuhammadUmer: That's not exactly true. In the same vein you could argue that the entirety of process memory is a bunch of global state. The question is more how you access that database. However, you're right in that a function that does I/O with another process or across the network is not a pure function, and "impurity" is part of what's problematic about global variables. – einpoklum Dec 25 '20 at 21:43

28 Answers28

287

The problem with global variables is that since every function has access to these, it becomes increasingly hard to figure out which functions actually read and write these variables.

To understand how the application works, you pretty much have to take into account every function which modifies the global state. That can be done, but as the application grows it will get harder to the point of being virtually impossible (or at least a complete waste of time).

If you don't rely on global variables, you can pass state around between different functions as needed. That way you stand a much better chance of understanding what each function does, as you don't need to take the global state into account.

Brian Rasmussen
  • 109,816
  • 33
  • 208
  • 305
  • 10
    This answer is really good. Combine this with the 'minimize variable scope' answer http://stackoverflow.com/questions/357187/global-variables-when-are-they-acceptable/357361#357361 – bobobobo Jun 25 '09 at 14:02
  • 23
    Substitute 'class' for 'application' and 'object state' for 'global state' and you make exactly the same argument for not using member variables (aka fields) in classes. The real answer is use them when appropriate. – Ian Goldby Nov 01 '11 at 12:40
  • people who get used to write firmware do the same for PC application which is not appropriate. because firmware is usually single threaded and simple – linquize Sep 11 '13 at 05:29
  • 2
    Few (perhaps silly) questions: 1) If you want to know which functions read and write these variables, couldn't you just use the "find" function in an editor to spot the cases where the values in these variables are modified? 2) "That can be done, ... a complete waste of time)." Can you give an example? 3) "If you don't rely on global variables, ... you don't need to take the global state into account." I don't understand how that is an advantage. Perhaps an example of that would work for me. – Andrei Nov 23 '13 at 12:27
  • @Andrey The problem of finding out where globals are referenced is not unsolvable, but it might be quite cumbersome. You can certainly search through the code base to detect where globals are referenced. If you have an IDE that understands the code, you might have good tool support to do this. If your IDE doesn't do this (or the language doesn't enable this), finding these places can be quite tedious. The point here is that if you pass state to the methods as needed. You only need to look at a given method to understand what is going on. That's far simpler. Does that make more sense? – Brian Rasmussen Nov 23 '13 at 19:43
  • @BrianRasmussen : I think I see what you are saying. Say, you are looking at someone else's code. You want to know in what sequence the variable is handled. In other words, what function uses the variable before/after what other function also uses the variable. – Andrei Nov 23 '13 at 22:08
  • +1 to Andrei; **+20234** to Ian. I'm about to convert my project from using a monolithic singleton instance, to move its members into `static` file variables where possible - and globals where the former is prohibitive/tedious. There is no point in having this as a singleton and the (probably _unimaginably tiny_) overhead of `get_instance()` and passing an irrelevant `this` pointer around. It's just a set of properties used by most functions of the program, which are logically grouped in TUs. I plan to use `static` variables where possible - globals the rest. Heresy! – underscore_d Apr 08 '16 at 12:28
  • 2
    @bobobobo broken link, can we get a screenshot from you, a 10k+ user? – noɥʇʎԀʎzɐɹƆ Jul 08 '16 at 22:01
  • 3
    @noɥʇʎԀʎzɐɹƆ Here you go! https://i.imgur.com/RwRgJLZ.jpg – Mateen Ulhaq Jul 29 '18 at 14:01
  • not sure I agree with this reasoning anymore, in a language that is single threaded, at anytime only one piece of code can modify it. The entire web runs on global state, which is database, it's atomic and it works. Databases are the massive global state yet it works, so? – Muhammad Umer Dec 08 '20 at 04:35
104

The important thing is to remember the overall goal: clarity

The "no global variables" rule is there because most of the time, global variables make the meaning of code less clear.

However, like many rules, people remember the rule, and not what the rule was intended to do.

I've seen programs that seem to double the size of the code by passing an enormous number of parameters around simply to avoid the evil of global variables. In the end, using globals would have made the program clearer to those reading it. By mindlessly adhering to the word of the rule, the original programmer had failed the intent of the rule.

So, yes, globals are often bad. But if you feel that in the end, the intent of the programmer is made clearer by the use of global variables, then go ahead. However, remember the drop in clarity that automatically ensues when you force someone to access a second piece of code (the globals) to understand how the first piece works.

Tom West
  • 1,487
  • 1
  • 11
  • 17
  • 8
    Suggesting using a global instead of passing variables is a recipe for making your code not reusable, and unsafe for multi-threading – Juan Mendes Dec 29 '12 at 01:11
  • 22
    Suggesting globals in the right circumstances is a recipe for clearer and higher performing code. "Passing" requires constant stack dynamic memory allocation, and this would be silly for something that ought to be a global, such as global buffer for incoming socket data. For example, if you have a function that reads Winsock recv(), why constantly create and deallocate this buffer within every call? Make the buffer a global. Multiple threads won't be reading it anyway. – James Aug 06 '13 at 22:06
  • Just curious, what program double the size of the code by passing parameters around to avoid global variables? In my experience, using global variables may solve data exposure problems, but there are usually additional complex logic that you need to add in order to make sure these magical variables behave properly. – user2167582 Feb 26 '18 at 03:31
  • 3
    If someone's passing around 100 variables, then they've not learnt what an object is. Using the reference to this object is then at worst passing around a pointer. I'd say that the rule isn't just clarity, but testability too - and using a non-global tends to make things much easier to test. – UKMonkey Jun 06 '18 at 13:52
  • 2
    "If someone's passing around 100 variables, then they've not learnt what an object is." Agreed, but not all the world is object-oriented. My personal example of doubling code size was a large Fortran program, circa 1986. As a fresh out of university employee, I "improved" it, by adding about 30 parameters to each call, eliminating all the globals. Then undid my improvement when I realized what I had wrought. – Tom West Jun 13 '18 at 19:48
  • Thanks for this answer cause I use globals in singletons. And I ignore the "globals are bad" crybabies. – GeneCode Sep 17 '19 at 13:45
67

My professor used to say something like: using global variables are okay if you use them correctly. I don't think I ever got good at using them correctly, so I rarely used them at all.

barneytron
  • 7,807
  • 3
  • 21
  • 25
  • 27
    So true. They are like gotos, if you don't know when to use them then never do. – David Holm Jan 28 '09 at 16:48
  • 5
    At my current company, they use `static` global variables a lot, language is C. Being confined to relatively small translation units, they begin resembling class variables of C++ objects. – Vorac Jan 29 '14 at 17:13
  • 1
    @Vorac static variables are not global variables, they are local variables. A global variable is a variable available everywhere in the program (hence "global", duh). Not to be confused with _file scope variables_, which are variables declared outside of any function. A static file scope variable is not a global variable. – Lundin May 07 '15 at 11:51
  • 1
    To correct myself, `program lifetime, file scope variables`. And they become quite global once you pass a pointer to the variable to the outside world (which is impossible with automatic variables).. – Vorac May 09 '15 at 08:45
  • @Lundin I agree, `static` Global variables have limited scope to the same translation unit. But they have lifetime till the end of the program as any global variable. – akhileshmoghe Dec 12 '16 at 14:05
  • What if you create a global variable and then comment where it is used and what function modifies it? – therealManUtdFan Jan 25 '21 at 21:05
43

The problem that global variables create for the programmer is that it expands the inter-component coupling surface between the various components that are using the global variables. What this means is that as the number of components using a global variable increases, the complexity of the interactions can also increase. This increased coupling usually makes defects easier to inject into the system when making changes and also makes defects harder to diagnose and correct. This increase coupling can also reduce the number of available options when making changes and it can increase the effort required for changes as often one must trace through the various modules that are also using the global variable in order to determine the consequences of changes.

The purpose of encapsulation, which is basically the opposite of using global variables, is to decrease coupling in order to make understanding and changing the source easier and safer and more easily tested. It is much easier to use unit testing when global variables are not used.

For example if you have a simple global integer variable that is being used as an enumerated indicator that various components use as a state machine and you then make a change by adding a new state for a new component, you must then trace through all the other components to ensure that the change will not affect them. An example of a possible problem would be if a switch statement to test the value of the enumeration global variable with case statements for each of the current values is being used in various places and it so happens that some of the switch statements do not have a default case to handle an unexpected value for the global all of a sudden you have undefined behavior so far as the application is concerned.

On the other hand the use of a shared data area might be used to contain a set of global parameters which are referenced throughout the application. This approach is often used with embedded applications with small memory footprints.

When using global variables in these sort of applications typically the responsibility for writing to the data area is allocated to a single component and all other components see the area as const and read from it, never writing to it. Taking this approach limits the problems that can develop.

A few problems from global variables which need to be worked around

When the source for a global variable such as a struct is modified, everything using it must be recompiled so that everything using the variable knows its true size and memory template.

If more than one component can modify the global variable you can run into problems with inconsistent data being in the global variable. With a multi-threading application, you will probably need to add some kind of locking or critical region to provide a way so that only one thread at a time can modify the global variable and when a thread is modifying the variable, all changes are complete and committed before other threads can query the variable or modify it.

Debugging a multi-threaded application that uses a global variable can be more difficult. You can run into race conditions that can create defects that are difficult to replicate. With several components communicating through a global variable, especially in a multi-threaded application, being able to know what component is changing the variable when and how it is changing the variable can be very difficult to understand.

Name clash can be a problem with using of global variables. A local variable that has the same name as a global variable can hide the global variable. You also run into the naming convention issue when using the C programming language. A work around is to divide the system up into sub-systems with the global variables for a particular sub-system all beginning with the same first three letters (see this on resolving name space collisions in objective C). C++ provides namespaces and with C you can work around this by creating a globally visible struct whose members are various data items and pointers to data and functions which are provided in a file as static hence with file visibility only so that they can only be referenced through the globally visible struct.

In some cases the original application intent is changed so that global variables that provided the state for a single thread is modified to allow several duplicate threads to run. An example would be a simple application designed for a single user using global variables for state and then a request comes down from management to add a REST interface to allow remote applications to act as virtual users. So now you run into having to duplicate the global variables and their state information so that the single user as well as each of the virtual users from remote applications have their own, unique set of global variables.

Using C++ namespace and the struct Technique for C

For the C++ programming language the namespace directive is a huge help in reducing the chances of a name clash. namespace along with class and the various access keywords (private, protected, and public) provide most of the tools you need to encapsulate variables. However the C programming language doesn't provide this directive. This stackoverflow posting, Namespaces in C , provides some techniques for C.

A useful technique is to have a single memory resident data area that is defined as a struct which has global visibility and within this struct are pointers to the various global variables and functions that are being exposed. The actual definitions of the global variables are given file scope using the static keyword. If you then use the const keyword to indicate which are read only, the compiler can help you to enforce read only access.

Using the struct technique can also encapsulate the global so that it becomes a kind of package or component that happens to be a global. By having a component of this kind it becomes easier to manage changes that affect the global and the functionality using the global.

However while namespace or the struct technique can help manage name clashes, the underlying problems of inter-component coupling which the use of globals introduces especially in a modern multi-threaded application, still exist.

Richard Chambers
  • 14,509
  • 3
  • 62
  • 86
38

Global variables should only be used when you have no alternative. And yes, that includes Singletons. 90% of the time, global variables are introduced to save the cost of passing around a parameter. And then multithreading/unit testing/maintenance coding happens, and you have a problem.

So yes, in 90% of the situations global variables are bad. The exceptions are not likely to be seen by you in your college years. One exception I can think off the top of my head is dealing with inherently global objects such as interrupt tables. Things like DB connection seem to be global, but ain't.

  • 2
    The one exception that *I* saw in my college years was graphics call-back functions. In XWindows, the mouse-callbacks didn't have void* data arguments that allowed you to pass around arbitrary chunks of program state... (not that that ends up being MUCH better than a global anyway...) – Brian Postow Feb 24 '10 at 16:10
  • 10
    +1 for "Things like DB connection *seem* to be global, but ain't." – R.. GitHub STOP HELPING ICE Oct 26 '10 at 19:43
  • 1
    Interrupt tables are not global, there's one per processor - but there's also one instance of your program per processor so it "cancels out". – user253751 Feb 21 '18 at 22:58
  • 1
    Can anyone please enlighten me on why DB connections aren't global (and what would be a good alternative)? I always thought of connections as one of the rare cases where globals were acceptable. – Floella Nov 28 '19 at 15:52
22

Global variables are as bad as you make them, no less.

If you are creating a fully encapsulated program, you can use globals. It's a "sin" to use globals, but programming sins are laregly philosophical.

If you check out L.in.oleum, you will see a language whose variables are solely global. It's unscalable because libraries all have no choice but to use globals.

That said, if you have choices, and can ignore programmer philosophy, globals aren't all that bad.

Neither are Gotos, if you use them right.

The big "bad" problem is that, if you use them wrong, people scream, the mars lander crashes, and the world blows up....or something like that.

Mankarse
  • 37,343
  • 9
  • 88
  • 138
user54650
  • 4,292
  • 2
  • 22
  • 27
  • 18
    Downplaying the problems of using globals to a confused student is not a good idea IMO. – GEOCHET Jan 27 '09 at 19:13
  • 4
    Design Philosophy is not objective. Not in the least. Just because most programmers don't like something, doesn't mean one should never look into that something. It is easy to make general-use of globals without the world ending. Let him do it, struggle (knowing he would), and learn how. – user54650 Jan 27 '09 at 21:22
  • 7
    Rich is right. This answer doesn't say anything about what is/isn't bad (or how globals can be used safely), only that "they're not as bad as all that. As such, it only downplays the problems. – jalf Mar 06 '09 at 13:37
  • 4
    I disagree that global variables are only as "bad as you make them". I think one of the main problems, especially in this multi-developer, interconnected world most of us live, work and program in, is that global variables give someone ELSE the opportunity to make your code bad. – gariepy Apr 08 '16 at 17:17
  • @gariepy until know i though the talk is about statics :D ok so that's that... and my app only have one or two global variable, that's one comes with Visual Studio, DEBUG and TRACE which we normally don't use :D – deadManN Jan 22 '19 at 09:03
  • kuddos for "neither are gotos if you use them right" – Shark Nov 04 '20 at 14:26
20

Yes, but you don't incur the cost of global variables until you stop working in the code that uses global variables and start writing something else that uses the code that uses global variables. But the cost is still there.

In other words, it's a long term indirect cost and as such most people think it's not bad.

GEOCHET
  • 20,623
  • 15
  • 71
  • 98
MSN
  • 49,698
  • 7
  • 70
  • 100
19

If it's possible your code will end up under intensive review during a Supreme Court trial, then you want to make sure to avoid global variables.

See this article: Buggy breathalyzer code reflects importance of source review

There were some problems with the style of the code that were identified by both studies. One of the stylistic issues that concerned the reviewers was the extensive use of unprotected global variables. This is considered poor form because it increases the risk that the program state will become inconsistent or that values will be inadvertently modified or overwritten. The researchers also expressed some concern about the fact that decimal precision is not maintained consistently throughout the code.

Man, I bet those developers are wishing they hadn't used global variables!

Casey
  • 5,511
  • 3
  • 28
  • 37
  • 6
    That was the best laugh I've had in a while. A true example of why closed source development for profit is bad, and a good example of global vars gone wrong! – Evil Spork Sep 17 '11 at 19:57
  • What is established here is that global variables are viewed with scorn. There is nothing here that shows that global variables were a genuine problem in the code. SysTest said that while the code was "not written in a manner consistent with usual software design best practices", that it would still "reliably produce consistent test results." So no harm from globals was actually documented. As I see it, they just established that, "Well, these dev's don't practice the same coding religion as the rest of the mainstream world." – LionKimbro Sep 11 '19 at 19:31
17

I'd answer this question with another question: Do you use singeltons/ Are singeltons bad?

Because (almost all) singelton usage is a glorified global variable.

Gavin Miller
  • 40,636
  • 19
  • 113
  • 178
  • 11
    I was about to post a smart comment saying, "They're only bad if you call them globals instead of singletons", but you beat me to it. – smo Jan 27 '09 at 18:50
  • I'm still trying to figure out what the hell singletons are LOL. – GeoffreyF67 Jan 27 '09 at 20:39
  • 1
    @Geoffrey: here are some good SO descriptions -- http://stackoverflow.com/questions/11831/singletons-good-design-or-a-crutch#11839 and for some good links: http://stackoverflow.com/questions/11831/singletons-good-design-or-a-crutch#65108 – Gavin Miller Jan 27 '09 at 21:13
  • 10
    For the record, a singleton is a global variable with a glorified Design Patterns(tm)(lol) name to make it sound legitimate. It's equally bad for all the same reasons. – R.. GitHub STOP HELPING ICE Oct 26 '10 at 19:41
  • @GavinMiller Are saying it's OK if you use the simpleton... ooops, singleton euphemism? – Juan Mendes Dec 28 '12 at 21:33
16

The issue is less that they're bad, and more that they're dangerous. They have their own set of pros and cons, and there are situations where they're either the most efficient or only way to achieve a particular task. However, they're very easy to misuse, even if you take steps to always use them properly.

A few pros:

  • Can be accessed from any function.
  • Can be accessed from multiple threads.
  • Will never go out of scope until the program ends.

A few cons:

  • Can be accessed from any function, without needing to be explicitly dragged in as a parameter and/or documented.
  • Not thread-safe.
  • Pollutes the global namespace and potentially causes name collisions, unless measures are taken to prevent this.

Note, if you will, that the first two pros and the first two cons I listed are the exact same thing, just with different wording. This is because the features of a global variable can indeed be useful, but the very features that make them useful are the source of all their problems.

A few potential solutions to some of the problems:

  • Consider whether they're actually the best or most efficient solution for the problem. If there are any better solutions, use that instead.
  • Put them in a namespace [C++] or singleton struct [C, C++] with a unique name (a good example would be Globals or GlobalVars), or use a standardised naming convention for global variables (such as global_[name] or g_module_varNameStyle (as mentioned by underscore_d in the comments)). This will both document their use (you can find code that uses global variables by searching for the namespace/struct name), and minimise the impact on the global namespace.
  • For any function that accesses global variables, explicitly document which variables it reads and which it writes. This will make troubleshooting easier.
  • Put them in their own source file and declare them extern in the associated header, so their use can be limited to compilation units that need to access them. If your code relies on a lot of global variables, but each compilation unit only needs access to a handful of them, you could consider sorting them into multiple source files, so it's easier to limit each file's access to global variables.
  • Set up a mechanism to lock and unlock them, and/or design your code so that as few functions as possible need to actually modify global variables. Reading them is a lot safer than writing them, although thread races may still cause problems in multithreaded programs.
  • Basically, minimise access to them, and maximise name uniqueness. You want to avoid name collisions and have as few functions as possible that can potentially modify any given variable.

Whether they're good or bad depends on how you use them. The majority tend to use them badly, hence the general wariness towards them. If used properly, they can be a major boon; if used poorly, however, they can and will come back to bite you when and how you least expect it.

A good way to look at it is that they themselves aren't bad, but they enable bad design, and can multiply the effects of bad design exponentially.


Even if you don't intend to use them, it is better to know how to use them safely and choose not to, than not to use them because you don't know how to use them safely. If you ever find yourself in a situation where you need to maintain pre-existing code that relies on global variables, you may be in for difficulty if you don't know how to use them properly.

  • 1
    +1 for pragmatism. A singleton often just adds boilerplate to make the instance & refactor into members, & you end up with... global variables, just masquerading under a different name. Why bother, other than to avoid the Sin of Globals on a mere technicality? Namespaces are nice as a barrier, but I find a simple `g_module_varNameStyle` perfectly legible. To be clear, I'm not using globals if I can avoid it easily - key word _easily_, because since I stopped believing they must be avoided - or rather **obfuscated** - at all costs, I'm having a much better time, & my code is (shock!) far tidier – underscore_d Apr 16 '16 at 23:37
  • @underscore_d It's mainly just to have a way to differentiate between global and local variables more easily, and also to make it easier to locate global variables when searching your code, with the intention being to prevent confusion over whether a variable is global or local/a parameter/a member/etc.. A standard naming convention like yours works just as well, as long as it's consistent. Editing my answer with the standard naming convention idea, thanks. – Justin Time - Reinstate Monica Apr 18 '16 at 22:00
  • 1
    "For any function ... explicitly document which variables" - remember this is a transitive relation. If function A calls functions B and C, then it reads and writes the variables written by both (plus the ones directly in it's body) – Caleth Feb 14 '18 at 10:14
11

As someone said (I'm paraphrasing) in another thread "Rules like this should not be broken, until you fully understand the consequences of doing so."

There are times when global variables are necessary, or at least very helpful (Working with system defined call-backs for example). On the other hand, they're also very dangerous for all of the reasons you've been told.

There are many aspects of programming that should probably be left to the experts. Sometimes you NEED a very sharp knife. But you don't get to use one until you're ready...

Brian Postow
  • 10,227
  • 14
  • 69
  • 113
  • 1
    I agree, if you understand the consequences, it's OK the break the rules, but if you catch yourself doing it often, you're doing something wrong – Juan Mendes Dec 28 '12 at 21:31
10

Using global variables is kind of like sweeping dirt under a rug. It's a quick fix, and a lot easier in the short term than getting a dust-pan or vacuum to clean it up. However, if you ever end up moving the rug later, you're gonna have a big surprise mess underneath.

gnovice
  • 123,396
  • 14
  • 248
  • 352
  • 1
    lazy metaphor devoid of context != answer – underscore_d Apr 08 '16 at 12:38
  • 1
    @underscore_d: I disagree. This is a discussion question, even though it isn't tagged as such (probably due to its age), and so answers like this are perfectly valid, and it makes a point that does address the OPs question. – gariepy Apr 08 '16 at 17:19
9

Global variables are generally bad, especially if other people are working on the same code and don't want to spend 20mins searching for all the places the variable is referenced. And adding threads that modify the variables brings in a whole new level of headaches.

Global constants in an anonymous namespace used in a single translation unit are fine and ubiquitous in professional apps and libraries. But if the data is mutable, and/or it has to be shared between multiple TUs, you may want to encapsulate it--if not for design's sake, then for the sake of anybody debugging or working with your code.

Michel
  • 1,418
  • 11
  • 15
7

Global variables are bad, if they allow you to manipulate aspects of a program that should be only modified locally. In OOP globals often conflict with the encapsulation-idea.

Leonidas
  • 2,344
  • 14
  • 21
7

I think your professor is trying to stop a bad habit before it even starts.

Global variables have their place and like many people said knowing where and when to use them can be complicated. So I think rather than get into the nitty gritty of the why, how, when, and where of global variables your professor decided to just ban. Who knows, he might un-ban them in the future.

bong
  • 164
  • 6
7

Absolutely not. Misusing them though... that is bad.

Mindlessly removing them for the sake of is just that... mindless. Unless you know the advanatages and disadvantages, it is best to steer clear and do as you have been taught/learned, but there is nothing implicitly wrong with global variables. When you understand the pros and cons better make your own decision.

jheriko
  • 2,928
  • 1
  • 19
  • 28
  • 3
    -1 There are numerous reasons to caution against global variables: the biggest one for me is that hidden dependencies and global make testing code in any predictable fashion extremely difficult. Unless you don't value the ability to test your code in an automated way I would suggest that global variables will cause you nothing but pain. And besides, in a well structured program there are *always* alternatives. – jkp Jul 03 '12 at 10:59
  • 1
    what you are saying is a massive overgeneralisation, careful use of global state doesn't prevent automated testing - in fact almost all apps have global state, whether it is wrapped as dynamically allocated instances of well encapsulated objects or static data which is totally exposed it makes no difference conceptually, there are still dependencies - it is just about how they are encoded. – jheriko Nov 24 '12 at 16:23
  • 1
    Exactly. They're not so much "bad" as they are "easily breakable", basically. If you know how to use them without breaking anything, and _when_ to use them instead of an alternative, they can be helpful. Otherwise... not so much. – Justin Time - Reinstate Monica Mar 16 '16 at 17:33
6

I would like to argue against the point being made throughout this thread that it makes multi-threading harder or impossible per se. Global variables are shared state, but the alternatives to globals (e. g. passing pointers around) might also share state. The problem with multi-threading is how to properly use shared state, not whether that state happens to be shared through a global variable or something else.

Most of the time when you do multi-threading you need to share something. In a producer-consumer pattern for example, you might share some thread-safe queue that contains the work units. And you are allowed to share it because that data structure is thread-safe. Whether that queue is global or not is completely irrelevant when it comes to thread-safety.

The implied hope expressed throughout this thread that transforming a program from single-threaded to multi-threaded will be easier when not using globals is naive. Yes, globals make it easier to shoot yourself in the foot, but there's a lot of ways to shoot yourself.

I'm not advocating globals, as the other points still stand, my point is merely that the number of threads in a program has nothing to do with variable scope.

Andreas Haferburg
  • 4,678
  • 1
  • 29
  • 52
5

No they are not bad at all. You need to look at the (machine) code produced by the compiler to make this determination, sometimes it is far far worse to use a local than a global. Also note that putting "static" on a local variable is basically making it a global (and creates other ugly problems that a real global would solve). "local globals" are particularly bad.

Globals give you clean control over your memory usage as well, something far more difficult to do with locals. These days that only matters in embedded environments where memory is quite limited. Something to know before you assume that embedded is the same as other environments and assume the programming rules are the same across the board.

It is good that you question the rules being taught, most of them are not for the reasons you are being told. The most important lesson though is not that this is a rule to carry with you forever, but this is a rule required to honor in order to pass this class and move forward. In life you will find that for company XYZ you will have other programming rules that you in the end will have to honor in order to keep getting a paycheck. In both situations you can argue the rule, but I think you will have far better luck at a job than at school. You are just another of many students, your seat will be replaced soon, the professors wont, at a job you are one of a small team of players that have to see this product to the end and in that environment the rules developed are for the benefit of the team members as well as the product and the company, so if everyone is like minded or if for the particular product there is good engineering reason to violate something you learned in college or some book on generic programming, then sell your idea to the team and write it down as a valid if not the preferred method. Everything is fair game in the real world.

If you follow all of the programming rules taught to you in school or books your programming career will be extremely limited. You can likely survive and have a fruitful career, but the breadth and width of the environments available to you will be extremely limited. If you know how and why the rule is there and can defend it, thats good, if you only reason is "because my teacher said so", well thats not so good.

Note that topics like this are often argued in the workplace and will continue to be, as compilers and processors (and languages) evolve so do these kinds of rules and without defending your position and possibly being taught a lesson by someone with another opinion you wont move forward.

In the mean time, then just do whatever the one that speaks the loudest or carries the biggest stick says (until such a time as you are the one that yells the loudest and carries the biggest stick).

old_timer
  • 62,459
  • 8
  • 79
  • 150
  • 4
    Is this just another way of saying "no one ever got fired for buying IBM"? – Gordon Potter Sep 04 '09 at 10:33
  • 1
    Good point that for some applications using global variables can actually make the work easier. In general using global variables is a source of problems with hidden pathways of coupling between sections of source. However having a shared memory area that is referenced as a global is used for a number implementations such as device interfaces or perhaps a global parameter table containing constants of various kinds or a jump table. – Richard Chambers Jul 01 '14 at 01:17
5

Yes, because if you let incompetent programmers use them (read 90% especially scientists) you end up with 600+ global variable spread over 20+ files and a project of 12,000 lines where 80% of the functions take void, return void, and operate entirely on global state.

It quickly becomes impossible to understand what is going on at any one point unless you know the entire project.

wezzman
  • 67
  • 1
  • 1
4

Global variables are fine in small programs, but horrible if used the same way in large ones.

This means that you can easily get in the habit of using them while learning. This is what your professor is trying to protect you from.

When you are more experienced it will be easier to learn when they are okay.

Darron
  • 20,463
  • 5
  • 47
  • 53
3

Global are good when it comes to configuration . When we want our configuration/changes to have a global impact on entire project.

So we can change one configuration and the changes are directed to entire project . But I must warn you would have to be very smart to use globals .

Maaz Rehman
  • 602
  • 5
  • 19
  • well no, the same thing can be accomplished without globals but rather a "configuration" class/struct passed to the "configuration manager" which then propagates it everywhere else. – Shark Nov 04 '20 at 14:22
  • That class would be holding those values and would be available on a global namespace, basically the same thing – Maaz Rehman Nov 06 '20 at 06:29
  • And class would represent Object oriented paradigm which may or may not be the case. – Maaz Rehman Nov 06 '20 at 06:31
2

Use of Global variables actually depends on the requirements. Its advantage is that,it reduces the overhead of passing the values repeatedly.

But your professor is right because it raises security issues so use of global variables should be avoided as much as possible. Global variables also create problems which are sometimes difficult to debug.

For example:-

Situations when the variables values is getting modified on runtime. At that moment its difficult to identify which part of code is modifying it and on what conditions.

Mufaddal Kagda
  • 140
  • 1
  • 10
2

In the end of the day, your program or app can still work but its a matter of being tidy and having a complete understanding of whats going on. If you share a variable value among all functions, it may become difficult to trace what function is changing the value(if the function does so) and makes debugging a million times harder

iliketocode
  • 6,652
  • 4
  • 41
  • 57
alaboudi
  • 2,442
  • 2
  • 22
  • 39
1

In web applications within an enterprize can be used for holding session/window/thread/user specific data on the server for reasons of optimization and to preserve against loss of work where connection are unstable. As mentioned, race conditions need to be handled. We use a single instance of a class for this information and it is carefully managed.

xxyzzy
  • 480
  • 4
  • 7
1

Sooner or later you will need to change how that variable is set or what happens when it is accessed, or you just need to hunt down where it is changed.

It is practically always better to not have global variables. Just write the dam get and set methods, and be gland you when you need them a day, week or month later.

Bloodboiler
  • 2,012
  • 2
  • 24
  • 21
1

I usually use globals for values that are rarely changed like singletons or function pointers to functions in dynamically loaded library. Using mutable globals in multithreaded applications tends to lead to hard to track bug so I try to avoid this as a general rule.

Using a global instead of passing an argument is often faster but if you're writing a multithreaded application, which you often do nowadays, it generally doesn't work very well (you can use thread-statics but then the performance gain is questionable).

-1

security is less means any one can manipulate the variables if they are declared global , for this one to explain take this example if you have balance as a global variable in your bank program the user function can manipulate this as well as bank officer can also manipulate this so there is a problem .only user should be given the read only and withdraw function but the clerk of the bank can add the amount when the user personally gives the cash in the desk.this is the way it works

-1

In a multi-threaded application, use local variables in place of global variables to avoid a race condition.

A race condition occurs when multiple thread access a shared resource, with at least one thread having a write access to the data. Then, the result of the program is not predictable, and depends on the order of accesses to the data by different threads.

More on this here, https://software.intel.com/en-us/articles/use-intel-parallel-inspector-to-find-race-conditions-in-openmp-based-multithreaded-code

kiriloff
  • 22,522
  • 32
  • 127
  • 207
  • For posterity: this is partly correct at best. The "local variables" in this answer refer to _thread_-local variables, rather than the more common scope-local variables that the OP is referring to. The side effects of modifying global variables in a thread-unsafe way are very different from those of changing global state in a non-concurrent way. – Jules Jul 24 '17 at 16:02