Should i avoid global variables




















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

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

Global variables should only be used when you have no alternative. And yes, that includes Singletons. 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. 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. 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.

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. The big "bad" problem is that, if you use them wrong, people scream, the mars lander crashes, and the world blows up 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.

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

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.

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

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. Mindlessly removing them for the sake of is just that When you understand the pros and cons better make your own decision. 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. 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.

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.

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. Constants are the colloquial examples for immutable states:. Most of the time, developers will call global states , global variables or globals what they should call instead global mutable states.

That is, a state which can be modified mutable in the biggest scope you can find: the whole application. At that point, you might think the following: how handy to have variables I can access and change everywhere!

I can share states from one part of the application to another! No need to pass them through functions and write so many lines of code!

Glory to the global mutable state! Imagine you have a big application with global variables. Each time you need to change something, you need to:. On top of that, your global mutable states can change anywhere in your application. Most of the time, you will have to guess their states. It means looking in the whole application, trying to guess the value of your globals in the scope you modify. Does another class, method or function will behave unexpectedly because of the change?

Good luck to find out. If n objects all know about each others, then a change to just one object can result in the other n-1 objects needing changes.

In short, you will couple every class, method and function which use these global states together. Does it afraid you? It should.

Humans are not good to take a lot of information into consideration at once. When we try to do so, our mental energy will go down, our focus as well, and we will create bugs and nonsense. Another thing to consider: using third party libraries. The dream of every developer! If this third party library use globals as well, with the same names that your own global variables, you will experience the pleasure of name collisions.

Your application will crash and you will wonder why, possibly for a while:. At each step, expect to lose some hairs from your rage and desperation. Your hairdresser will be out of work quickly. Nobody wants that. Some of you might remember Javascript libraries like Mootools, Underscore and jQuery always colliding which each other, if you would not wrap them in smaller scopes than the global one.

Since your tests might change your globals, you will never be sure what are their states in any test. Did you ever have tests succeeding in isolation, but failing when you were executing the whole test suit? I did. Pain is always vivid when I think about it. Mutable global states can bring many problems if you need to do some concurrency.

It makes sense: if you change the state of your globals on multiple threads, expect to take a big race condition in your face. These HTTP parameters sent to the server could be needed in multiple layers of your application.

Add concurrency for each request on top, and you will have a good recipe for disasters. Global mutable states can as well be backed directly in the language implementation. For example, PHP has superglobals. Whenever your globals come from, how to manage them?

The simplest way to avoid globals all together is to simply pass your variables using function arguments. We could have made this array of parameters global, when we extract it from the HTTP request. It seems easier: no need to pass the data in four different function. Using globals would make the code less understandable and couple the methods to each other, which is a very high price for almost no benefit. If you need to add even more, the complexity of the function will rise! And what about variables, objects or whatever construct you need almost everywhere?

You pass them to every function in your application? These questions are legitimate, dear reader. One of the key reasons to declare local variables as close to where they are used as possible is because doing so minimizes the amount of code you need to look through to understand what the variable does. Global variables are at the opposite end of the spectrum -- because they can be accessed anywhere, you might have to look through the entire program to understand their usage.

In small programs, this might not be an issue. In large ones, it will be. Global variables also make your program less modular and less flexible. A function that utilizes nothing but its parameters and has no side effects is perfectly modular.

Modularity helps both in understanding what a program does, as well as with reusability. Global variables reduce modularity significantly. It is much more likely to break if you change a global variable that impacts how your program actually functions.

The initialization order problem of global variables. Initialization of static variables which includes global variables happens as part of program startup, before execution of the main function. This proceeds in two phases. The first phase is called static initialization. In the static initialization phase, global variables with constexpr initializers including literals are initialized to those values.

Also, global variables without initializers are zero-initialized. The second phase is called dynamic initialization. This phase is more complex and nuanced, but the gist of it is that global variables with non-constexpr initializers are initialized. Within a single file, global variables are generally initialized in order of definition there are a few exceptions to this rule.



0コメント

  • 1000 / 1000