265

I just ran across this old question asking what's so evil about global state, and the top-voted, accepted answer asserts that you can't trust any code that works with global variables, because some other code somewhere else might come along and modify its value and then you don't know what the behavior of your code will be because the data is different! But when I look at that, I can't help but think that that's a really weak explanation, because how is that any different from working with data stored in a database?

When your program is working with data from a database, you don't care if other code in your system is changing it, or even if an entirely different program is changing it, for that matter. You don't care what the data is; that's the entire point. All that matters is that your code deals correctly with the data that it encounters. (Obviously I'm glossing over the often-thorny issue of caching here, but let's ignore that for the moment.)

But if the data you're working with is coming from an external source that your code has no control over, such as a database (or user input, or a network socket, or a file, etc...) and there's nothing wrong with that, then how is global data within the code itself--which your program has a much greater degree of control over--somehow a bad thing when it's obviously far less bad than perfectly normal stuff that no one sees as a problem?

Mason Wheeler
  • 83,213

22 Answers22

118

First, I'd say that the answer you link to overstates that particular issue and that the primary evil of global state is that it introduces coupling in unpredictable ways that can make it difficult to change the behaviour of your system in future.

But delving into this issue further, there are differences between global state in a typical object-oriented application and the state that is held in a database. Briefly, the most important of these are:

  • Object-oriented systems allow replacing an object with a different class of object, as long as it is a subtype of the original type. This allows behaviour to be changed, not just data.

  • Global state in an application does not typically provide the strong consistency guarantees that a database does -- there are no transactions during which you see a consistent state for it, no atomic updates, etc.

Additionally, we can see database state as a necessary evil; it is impossible to eliminate it from our systems. Global state, however, is unnecessary. We can entirely eliminate it. So even were the issues with a database just as bad, we can still eliminate some of the potential problems and a partial solution is better than no solution.

Jules
  • 17,880
  • 2
  • 38
  • 65
76

First, what are the problems with global variables, based on the accepted answer to the question you linked?

Very briefly, it makes program state unpredictable.

Databases are, the vast majority of the time, ACID compliant. ACID specifically addresses the underlying issues that would make a data store unpredictable or unreliable.

Further, global state hurts the readability of your code.

This is because global variables exist in a scope far away from their usage, maybe even in a different file. When using a database, you are using a record set or ORM object that is local to the code you are reading (or should be).

Database drivers typically provide a consistent, understandable interface to access data that is the same regardless of problem domain. When you get data from a database, your program has a copy of the data. Updates are atomic. Contrast to global variables, where multiple threads or methods may be operating on the same piece of data with no atomicity unless you add synchronization yourself. Updates to the data are unpredictable and difficult to track down. Updates may be interleaved, causing bog-standard textbook examples of multithreaded data corruption (e.g. interleaved increments).

Databases typically model different data than global variables to begin with, but leaving that aside for a moment, databases are designed from the ground-up to be an ACID-compliant data store that mitigates many of the concerns with global variables.

44

I'd offer a few observations:

Yes, a database is global state.

In fact, it's a super-global state, as you pointed out. It's universal! Its scope entails anything or anyone that connects to the database. And, I suspect lots of folks with years of experience can tell you horror stories about how "strange things" in the data led to "unexpected behavior" in one or more of the relevant applications...

One of the potential consequences of using a global variable is that two distinct "modules" will use that variable for their own distinct purposes. And to that extent, a database table is no different. It can fall victim to the same problem.

Hmm ... Here's the thing:

If a module doesn't operate extrinsically in some way, it does nothing.

A useful module can be given data or it can find it. And, it can return data or it can modify state. But, if it doesn't interact with the external world in some way, it may as well do nothing.

Now, our preference is to receive data and return data. Most modules are simply easier to write if they can be written with utter disregard for what the outside world is doing. But ultimately, something needs to find the data and modify that external, global state.

Furthermore, in real-world applications, the data exists so that it can be read and updated by various operations. Some issues are prevented by locks and transactions. But, preventing these operations from conflicting with each other in principle, at the end of the day, simply involves careful thinking. (And making mistakes...)

But also, we're generally not working directly with the global state.

Unless the application lives in the data layer (in SQL or whatever), the objects our modules work with are actually a copies of the shared global state. We can do whatever we want those without any impact to the actual, shared state.

And, in cases where we need to mutate that global state, under the assumption that the data we were given hasn't changed, we can generally perform the same-ish sort of locking that we would on our local globals.

And finally, we usually do different things with databases than we might with naughty globals.

A naughty, broken global looks like this:

Int32 counter = 0;

public someMethod() {
  for (counter = 0; counter < whatever; counter++) {
    // do other stuff.
  }
}

public otherMethod() {
  for (counter = 100; counter < whatever; counter--) {
    // do other stuff.
  }
}

We simply don't use databases for in-process/operational stuff like that. And it might be the slow nature of the database and the relative convenience of a simple variable that deters us: Our sluggish, awkward interaction with databases simply make them bad candidates for many of the mistakes we've historically made with variables.

svidgen
  • 15,252
25

I disagree with the fundamental claim that:

When your program is working with data from a database, you don't care if other code in your system is changing it, or even if an entirely different program is changing it, for that matter.

My initial thought was "Wow. Just Wow". So much time and effort is spent trying to avoid exactly this - and working out what trade-offs and compromises work for each application. To just ignore it is a recipe for disaster.

But I also diasgree on an architectural level. A global variable is not just global state. It's global state that is accessible from anywhere transparently. In contrast to use a database you need to have a handle to it - (unless you store than handle in a global variable....)

For example using a global variable might look like this

int looks_ok_but_isnt() {
  return global_int++;
}

int somewhere_else() {
  ...
  int v = looks_ok_but_isnt();
  ...
}

But doing the same thing with a database would have to be more explicit about what its doing

int looks_like_its_using_a_database( MyDB * db ) {
   return db->get_and_increment("v");
}

int somewhere_else( MyBD * db ) { 
   ...
   v = looks_like_its_using_a_database(db);
   ...
}

The database one is obviously mucking with a database. If you wanted to not use a database you can use explicit state and it looks almost the same as the database case.

int looks_like_it_uses_explicit_state( MyState * state ) {
   return state->v++;
}


int somewhere_else( MyState * state ) { 
   ...
   v = looks_like_it_uses_explicit_state(state);
   ...
}

So I would argue using a database is much more like using explicit state, than using global variables.

17

The point that the sole reason global variables can't be trusted since the state can be changed somewhere else is, in itself, not reason enough to not use them, agreed (it's a pretty good reason though!). It's likely the answer was mainly describing usage where restricting a variable's access to only areas of code that its concerned with would make more sense.

Databases are a different matter, however, because they're designed for the purpose of being accessed "globally" so to speak.

For example:

  • Databases typically have built in type and structure validation that goes further than the language accessing them
  • Databases almost unanimously update based off transactions, which prevents inconsistent states, where there's no guarantees what the end state will look like in a global object (unless it's hidden behind a singleton)
  • Database structure is at least implicitly documented based off table or object structure, more-so than the application utilizing it

Most importantly though, databases serve a different purpose than a global variable. Databases are for storing and searching large quantities of organized data, where global variables serve specific niches (when justifiable).

13

But when I look at that, I can't help but think that that's a really weak explanation, because how is that any different from working with data stored in a database?

Or any different from a working with an interactive device, with a file, with shared memory, etc. A program that does exactly the same thing every time it runs is a very boring and rather useless program. So yes, it's a weak argument.

To me, the difference that make a difference with regard to global variables is that they form hidden and unprotected lines of communication. Reading from a keyboard is very obvious and protected. I have to make a certain function call, and I cannot access the keyboard driver. The same applies to file access, shared memory, and your example, databases. It's obvious to the reader of the code that this function reads from the keyboard, that function accesses a file, some other function accesses shared memory (and there had better be protections around that), and yet some other function accesses a database.

With global variables, on the other hand, its not obvious at all. The API says to call foo(this_argument, that_argument). There's nothing in the calling sequence that says the global variable g_DangerWillRobinson should be set to some value but before calling foo (or examined after calling foo).


Google banned the use of non-const reference arguments in C++ primarily because it is not obvious to the reader of the code that foo(x) will change x because that foo takes a non-constant reference as an argument. (Compare with C#, which dictates that both the function definition and the call site must qualify a reference parameter with the ref keyword.) While I do not agree with the Google standard on this, I do understand their point.

Code is written once and modified a few times, but if it's at all good, it is read many, many times. Hidden lines of communications are very bad karma. C++'s non-const reference represent a minor hidden line of communication. A good API or a good IDE will show me that "Oh! This is call by reference." Global variables are a huge hidden line of communication.

David Hammen
  • 8,391
8

I think that the quoted explanation oversimplifies the issue to the point where the reasoning becomes ridiculous. Of course, the state of an external database contributes to the global state. The important question is how your program depends on the (mutable) global state. If a library function to split strings on white-space would depend on intermediary results stored in a database, I would object to this design at least as much as I would object to a global character array used for the same purpose. On the other hand, if you decide that your application doesn't need a full-blown DBMS to store business data at this point and a global in-memory key-value structure will do, this is not necessarily a sign of poor design. What is important is that – no matter what solution you pick to store your data – this choice is isolated to a very small portion of the system so most components can be agnostic to the solution chosen for deployment and unit-tested in isolation and the deployed solution can be changed at a later time with little effort.

5gon12eder
  • 7,236
7

Depending on what aspect you're judging, global variables and database access may be worlds apart, but as long as we're judging them as dependencies, they are the same.

Let's consider functional programming's definition of a pure function states that it must depends solely on the parameters it takes as inputs, producing a deterministic output. That is, given the same set of arguments twice, it must produce the same result.

When a function depends on a global variable, it can no longer be considered pure, since, for the same set or arguments, it may yield different outputs because the value of the global variable may have changed between the calls.

However, the function can still be seen as deterministic if we consider the global variable as much a part of the function's interface as its other arguments, so it isn't the problem. The problem is only that this is hidden until the moment we are surprised by unexpected behavior from seemingly obvious functions, then go read their implementations to discover the hidden dependencies.

This part, the moment where a global variable becomes a hidden dependency is what is considered evil by us programmers. It makes the code harder to reason about, hard to predict how it will behave, hard to reuse, hard to test and especially, it increases debug and fix time when a problem occurs.

The same thing happens when we hide the dependency on the database. We can have functions or objects making direct calls to database queries and commands, hiding these dependencies and causing us the exact same trouble that global variables cause; or we can make them explicit, which, as it turns out, is considered a best-practice that goes by many names, such as repository pattern, data-store, gateway, etc.

P.S.: There are other aspects which are important to this comparison, such as whether concurrency is involved, but that point is covered by other answers here.

7

As a software engineer working predominantly with embedded firmware, I'm almost always using global variables for anything going between modules. In fact, it's best practise for embedded. They are assigned statically, so there's no risk of blowing the heap/stack and there's no extra time taken for stack allocation/clean-up on function entry/exit.

The downside of this is that we do have to consider how those variables are used, and a lot of that comes down to the same kind of thought that goes into database-wrangling. Any asynchronous read/writes of variables MUST be atomic. If more than one place can write a variable, some thought must go into making sure they always write valid data, so the previous write is not arbitrarily replaced (or that arbitrary replacement is a safe thing to do). If the same variable is read more than once, some thought must go into considering what happens if the variable changes value between reads, or a copy of the variable must be taken at the start so that processing is done using a consistent value, even if that value becomes stale during processing.

(For that last one, on my very first day of a contract working on an aircraft countermeasures system, so highly safety-related, the software team were looking at a bug report they'd been trying to figure out for a week or so. I'd had just enough time to download the dev tools and a copy of the code. I asked "couldn't that variable be updated between reads and cause it?" but didn't really get an answer. Hey, what does the new guy know, after all? So whilst they were still discussing it, I added protective code to read the variable atomically, did a local build, and basically said "hey guys, try this". Way to prove I was worth my contracting rate. :)

So global variables are not an unambiguously bad thing, but they do leave you open to a wide range of issues if you don't think about them carefully.

David Hammen
  • 8,391
Graham
  • 2,062
6

Okay, let's start from the historical point.

We're in an old application, written in your typical mix of assembly and C. There's no functions, just procedures. When you want to pass an argument or return value from a procedure, you use a global variable. Needless to say, this is quite hard to keep track of, and in general, every procedure can do whatever it wants with every global variable. Unsurprisingly, people turned to passing arguments and return values in a different way as soon as it was feasible (unless it was performance critical not to do so - e.g. look at the Build Engine (Duke 3D) source code). The hate of global variables was born here - you had very little idea what piece of global state each procedure would read and change, and you couldn't really nest procedure calls safely.

Does this mean that global variable hate is a thing of the past? Not quite.

First, I have to mention that I've seen the exact same approach to passing arguments in the project I'm working on right now. For passing two reference type instances in C#, in a project that's about 10 years old. There's literally no good reason to do it like this, and was most likely born out of either cargo-culting, or a complete misunderstanding of how C# works.

The bigger point is that by adding global variables, you're expanding the scope of every single piece of code that has access to that global variable. Remember all those recommendations like "keep your methods short"? If you have 600 global variables (again, real-world example :/), all your method scopes are implicitly expanded by those 600 global variables, and there's no simple way to keep track of who has access to what.

If done wrong (the usual way :)), global variables may have coupling between each other. But you have no idea how they are coupled, and there's no mechanism to ensure that the global state is always consistent. Even if you introduce critical sections to try and keep things consistent, you'll find that it compares poorly to a proper ACID database:

  • There's no way to rollback a partial update, unless you preserve the old values before the "transaction". Needless to say, by this point, passing a value as an argument is already a win :)
  • Everyone accessing the same state must adhere to the same synchronization process. But there's no way to enforce this - if you forget to setup the critical section, you're screwed.
  • Even if you correctly synchronize all access, there might be nested calls that access partially modified state. This means that you either deadlock (if your critical sections aren't reëntrant), or deal with inconsistent data (if they are reëntrant).

Is it possible to resolve these issues? Not really. You need encapsulation to handle this, or really strict discipline. It's hard to do things right, and that's generally not a very good recipe for success in software development :)

Smaller scope tends to make code easier to reason about. Global variables make even the simplest pieces of code include huge swathes of scope.

Of course, this doesn't mean that global scoping is evil. It just shouldn't be the first solution you go for - it's a typical example of "simple to implement, hard to maintain".

Luaan
  • 1,860
6

A global variable is a tool, it can be used for good and for evil.

A database is a tool, it can be used for good and for evil.

As the original poster notes, the difference isn't all that big.

Inexperienced students often think that bugs is something that happen to other people. Teachers use "Global variables are evil" as a simplified reason to penalize bad design. Students generally doesn't understand that just because their 100-line program is bug free doesn't mean that the same methods can be used for 10000-line programs.

When you work with databases, you cannot just ban global state since that's what the program is all about. Instead you get more details guidelines like ACID and Normal Forms and so on.

If people used the ACID approach to global variables, they wouldn't be so bad.

On the other hand, if you design databases badly, they can be nightmares.

5

To me, the primary evil is Globals have no protection against concurrency issues. You can add mechanisms to handle such issues with Globals, but you'll find that the more concurrency issues you solve, the more your Globals start to mimick a database. The secondary evil is no contract on usage.

5

Some of the other answers try to explain why using a database is good. They are wrong! A database is global state and as such is just as evil as a singleton or a global variable. It is all kinds of wrong to use a database when you can easily just use a local Map or an Array instead!

Global variables allow global access, which carries risk of abuse. Global variables also have upsides. Global variables are generally said to be something you should avoid, not something you should never ever use. If you can easily avoid them you should avoid them. But if the benefits outweigh the drawbacks, of course you should use them!*

The exact same thing** applies to databases, which are global state - just like global variables are. If you can make do without accessing a database, and the resulting logic does all you need and is equally complex, using a database adds increased risk to your project, without any corresponding benefit.

In real life, many applications require global state by design, sometimes even persistent global state - that's why we have files, databases, etc.


*The exception here are students. It makes sense to prohibit students from using global variables so they have to learn what the alternatives are.

** Some answers incorrectly claim that databases are somehow better protected than other forms of global state (the question is explicitly about global state, not just global variables). That's bollocks. The primary protection offered in the database scenario is by convention, which is exactly the same for any other global state. Most languages also allow a lot of additional protection for global state, in form of const, classes that simply don't allow changing their state after it's been set in the constructor, or getters and setters that can take thread information or program state into account.

Peter
  • 3,778
2

In a sense, the distinction between global variables and a database is similar to the distinction between private and public members of an object (assuming anybody still uses public fields). If you think of the entire program as an object, then the globals are the private variables, and the database is the public fields.

They key distinction here is one of assumed responsibility.

When you write an object, it is assumed that anyone who maintains the member methods will ensure private fields remain well behaved. But you already give up any assumptions about the state of public fields and treat them with extra care.

The same assumption applies at a wider level to globals v/s database. Also, the programming language/ecosystem guarantees access restrictions on private v/s public in the same was as it enforces them on (nonshared memory) globals v/s database.

When multithreading comes into play, the concept of private v/s public v/s global v/s database is merely distinctions along a spectrum.

static int global; // within process memory space
static int dbvar; // mirrors/caches data outside process memory space

class Cls {
    public: static int class_public; // essentially the same as global
    private: static int class_private; // but public to all methods in class

    private: static void method() {
        static int method_private; // but public to all scopes in method
        // ...
        {
            static int scope1_private; // mutex guarded
            int the_only_truly_private_data;
        }
        // ...
        {
            static int scope2_private; // mutex guarded
        }
    }
}
1

A database can be a global state, but it doesn't have to be all the time. I disagree with the assumption that you don't have control. One way to manage that is locking and security. This can be done at the record, table or entire database. Another approach is to have some sort of version field that would prevent the changing of a record if the data are stale.

Like a global variable, the value(s) in a database can be changed once they are unlock, but there are many ways to control the access (Don't give all the devs the password to the account allowed to change data.). If you have a variable that has limited access, it's not very global.

JeffO
  • 36,956
0

Of course globals are not always inappropriate. They exist because they have a legitimate use. The main problem with globals, and the primary source of the admonition to avoid them, is that code that uses a global is attached to that one and only one global.

For example, consider an HTTP server storing the server name.

If you store the server name in a global, then the process cannot concurrently run logic for two different server names. Perhaps the original design never contemplated running more than one server instance at a time, but if you later decide you want to do that, you simply can't if the server name is in a global.

By contrast, if the server name is in a database, there is no problem. You can simply create one instance of that database for each instance of the HTTP server. Because each instance of the server has its own instance of the database, it can have its own server name.

So the primary objection to globals, there can be only one value for all code that accesses that global, does not apply to database entries. The same code can easily access distinct database instances that have different values for a particular entry.

0

I think this is an interesting question but it's a little difficult to answer because there are two main issues that are being conflated under the term 'global state'. The first is the concept of 'global coupling'. The proof of that is that the alternative given for global state is dependency injection. The thing is that DI doesn't necessarily eliminate global state. That is, it's absolutely possible and common to inject dependencies on global state. What DI does is remove the coupling that comes with global variables and the commonly used Singleton pattern. It aside from a slightly less obvious design, there's very little downside to eliminating this kind of coupling and the benefits of eliminating the coupling increases exponentially with the number of dependencies on those globals.

The other aspect of this is shared state. I'm not sure if there's a really clear distinction between globally shared state and shared state in general but the costs and benefits are much more nuanced. Simply put there are innumerable software systems that require shared state to be useful. Bitcoin, for example, is a very clever way of sharing state globally (literally) in a decentralized manner. Sharing mutable state properly without creating huge bottlenecks is difficult but useful. So if you don't really need to do it, you can simplify your application by minimizing shared mutable state.

So the question of how databases differ from globals is also bifurcated across these two aspects. Do they introduce coupling? Yes, they can but it depends a lot on how the application is designed and how the database is designed. There are too many factors to have a single answer to whether databases introduce global coupling without details of the design. As to whether they introduce sharing of state, well, that's kind of the main point of a database. The question is whether they do it well. Again, I think this is too complicated to answer without a lot of other pieces of information such as the alternatives and many other trade-offs.

JimmyJames supports Canada
  • 30,578
  • 3
  • 59
  • 108
0

I would think about it slightly differently: "global variable" like behavior is a price paid by database administrators (DBAs) because it is a necessary evil to do their job.

The issue with global variables, as several others have pointed out, is not an arbitrary one. The issue is that their use makes the behavior of your program less and less predictable because it becomes harder to determine who is using the variable and in what way. This is a big issue for modern software, because modern software is typically asked to do many many flexible things. It may do billions or even trillions of complex state manipulations during the course of a run. The ability to prove true statements about what that software will do in those billions or trillions of operations is extremely valuable.

In the case of modern software, all of our languages provide tools to assist in this, such as encapsulation. The choice not to use it is needless, which leads to the "globals are evil" mentality. In many regions of the software development field, the only people using them are people who don't know how to code better. This means they not only are trouble directly, but they indirectly suggest the developer did not know what they were doing. In other regions, you'll find globals are totally normal (embedded software, in particular, loves globals, partially because they work well with ISRs). However, amidst the many software developers out there, they are the minority voice, so the only voice you hear are "globals are evil."

Database development is one of those minority voice situations. The tools needed to do DBA work are very powerful, and their theory is not rooted in encapsulation. To eek out every single jiffy of performance out of their databases, they need full unfettered access to everything, similar to globals. Wield one of their monsterous 100 million row (or more!) databases, and you'll appreciate why they don't let their DB engine hold any punches.

They pay a price for that, a dear price. DBAs are forced to be almost pathological with their attention to detail, because their tools don't protect them. The best they have in the way of protection is ACID or perhaps foreign keys. Those that are not pathological find themselves with an utter mess of tables that is completely unusable, or even corrupt.

It's not uncommon to have 100k line software packages. In theory, any line in the software may affect any global at any point in time. In DBAs, you never find 100k different queries that can modify the database. That would be unreasonable to maintain with the attention to detail needed to protect you from yourself. If a DBA has anything large like that, they will intentionally encapsulate their database using accessors, sidestepping the "global like" issues, and then do as much work as they possibly can through that "safer" mechanism. Thus, when push comes to shove, even the database people avoid globals. They simply come with a lot of danger, and there are alternatives that are just as strong, but not as dangerous.

Would you rather walk around on broken glass, or on nicely swept sidewalks, if all other things are equal? Yes, you can walk on broken glass. Yes, some people even make a living doing it. But still, just let them sweep the sidewalk and move on!

Cort Ammon
  • 11,917
  • 3
  • 26
  • 35
0

I think the premise is false. There's no reason a database needs to be "global state" rather than a (very large) context object. If you're binding to the particular database your code is using via global variables or a fixed global database connection parameters, it's no different, and no less evil, than any other global state. On the other hand, if you properly pass around a context object for the database connection, it's just big (& widely used) contextual state, not global state.

Measuring the difference is easy: could you run two instances of your program logic, each using its own database, in a single program/process without making invasive changes to the code? If so, your database is not really "global state".

0

Short version

If you used a database as an application variable store (which would be easy to do) the values would be global with all of the problems that bring, and it would be slower. But we don’t do that.

Long version

First, my answer to that question points out that it isn’t unpredictable, it’s difficult to reason about. Those are different things. It is tedious and time consuming to figure out what the value would be at any particular point in time, but if you follow the execution flow, it’s certain possible.

As for the difference between a database and global variables, in one respect the database is harder to deal with - by its very nature, it is not limited to the currently running application, so the data can vary more easily and it may indeed be impossible to determine what the value is at any point in the program flow.

Other than the distributed nature of the db, theoretically there is no fundamental difference between the two, but practically speaking accessing a database is going to be both slower and more complex.

This practical difference makes most comparisons as meaningful as asking why we don’t use motorcycles to navigate around our house, to go to the kitchen or the bathroom.

We use global variables/singletons differently than we do a database. Global variables are used for state of the application information, which we want to access easily and quickly to control what the application does (classic example would be what database the application uses). While the database is used for the data that application acts on, which is expected to take longer to access and in a sense be more ephemeral.

This means that most of the differences in the database are irrelevant to the programmer - the application doesn’t care if the user name is rob, robert, rob@rt, or sandy, it doesn’t change the applications behavior.

Even when the difference is relevant (say roles), it is treated differently and in a more data agnostic manner.

In summary, theoretically they could be considered the same, but practically speaking we treat them sufficiently differently that their overlap is seldom important.

jmoreno
  • 11,238
-1

There are several differences:

  • A database value can be modified on the fly. The value of a global that is set in code on the other hand, cannot be changed unless you redeploy your application and modify your code. In fact, this is intentional. A database is for values that might change over time, but global variables should only be for things that will never change and when they do not contain actual data.

  • A database value (row,column) has a context and a relational mapping in the database. This relation can be easily extracted and analysed using tools like Jailer (for instance). A global variable on the other hand, is slightly different. You can find all the usages, but it would be impossible for you to tell me all the ways in which the variable interacts with the rest of your world.

  • Global variables are faster. Getting something from a database requires a database connection to be made, a select to me run and then the database connection must be closed. Any type conversions you might need come on top of that. Compare that to a global being accessed in your code.

These are the only that I can think of right now, but I'm sure there are more. Simply put, they are two different things and should be used for different objectives.

-2

Globals are not evil; they are simply a tool. MISUSE of globals is problematic, as is the misuse of any other programming feature.

My general recommendation is that globals should only be used in situations that are well understood and thought out, where other solutions are less optimal. Most importantly, you want to ensure that you have well documented where that global value might be modified, and if you are running multithreaded, that you are ensuring that global and any co-dependent globals are access in a way that is transactional.