Are global variable evil?

  • Thread starter Thread starter LP
  • Start date Start date
L

LP

After a code review one coworker insisted that global are very dangerous. He
didn't really give any solid reasons other than, "performance penalties",
"hard to maintain", and "dangerous". I think that I am using them
appropriate in class in question. One typical example: This class initiates
TCP session, keeps sending commands to the server app and gets messages and
codes back, message and code are stored in global variables to be preserved
them between method calls.

He insists I should not have any global variables, but instead passes them
from one method to the next. I think it's dumb. What's so bad about global
variables?



Thanks
 
The basic rule is "encapsulate", or said "isolate", that is isolate the
variable or code at where it should be seen, and don't let others see
it or touch(set) it if it's none of his business.

consider one thing: you know how to use it, others don't know, if it
can be modified by other coworkers, it's dangerous, he may modified by
mis-operation, and change your variable to a status which is nonsense
or invalid.

But, there should be a ballance. For an example, if it's a
GlobalLogger, pass it as a param to every method is stupid.

As to your problem, if it's only used by yourself you should
encapsulate it, if not, you should think the whole process over to
decide to expose it as global or encapsulate with public GetXX and
public/private SetXX.
 
The problem with a global variable is that its value can
be changed by _any_ code, in _any_ way, _anywhere_
in a program.

Therefore, when a bug arises that is suspected to be
related to that variable, the area of code to be searched
is: the entire program.

In addition, each piece of code that changes the global variable
must be restudied to understand what is happening.

Hence, good practice is to stash the variable in a class,
perhaps a singleton class, making it available via properties
or methods. Bugs related thereto are 'relatively' easier
to find and fix because the acreage to search is smaller.
--
Grace + Peace,
Peter N Roth
Engineering Objects International
http://engineeringobjects.com
Home of Matrix.NET
 
It is not clear what you mean by a "global variable". If you mean that you
create a class level static variable in the situation you describe, then are
definitely wrong. If you mean that you make class level variables "public" to
other classes, then you are also wrong. The whole software industry has said
this for years now. If you want to know why, then ask again, and I'll give
you some reasons.

Let's assume that you mean something else. From the context, it looks like
your "global variable" is a non static field for a class.

I tend to agree with your co-worker, but I am not 100% dogmatic about it. In
general, I only create a class "field" if there is a need for the value to
persist between different public method calls to an object instance. eg. Our
class stores an integer, and we have public methods to read and write that
integer, so we make a "global" field. So, in general, I don't create a field
to save a value which can be passed as a parameter between methods, but is
not needed to be stored. However, I don't make an absolute rule about this.
Sometimes, if their is a deep heirarchy in the implementation of a method,
and a value which is used throughout, then I will make it a field, but I put
a clear comment on the field stating why it is a field, and it's
limitiations.
 
LP said:
After a code review one coworker insisted that global are very dangerous.
He didn't really give any solid reasons other than, "performance
penalties", "hard to maintain", and "dangerous". I think that I am using
them appropriate in class in question.

He insists I should not have any global variables, but instead passes them
from one method to the next. I think it's dumb. What's so bad about global
variables?

What your friend has done is very common, I've seen it many times before.
Someone tells someone what is a good programming practice and the person
being told takes it too far. This is usually mixed in with a bit of
misunderstanding to make things worse. He is correct in that global
variables should generally be avoided but if one is appropriate then don't
go jumping through all sorts of hoops to avoid it.
One typical example: This class initiates TCP session, keeps sending
commands to the server app and gets messages and codes back, message and
code are stored in global variables to be preserved them between method
calls.

When he said global variables I'm sure he didn't mean variables defined
within the scope of one class but variables that the entire app can see. Any
variable defined as public and static within a class is essentially a global
variable.

I better way to have put it would be that a variable should have the minimum
scope it needs. That means variables shouldn't be global if they can be
defined in a class, variables shouldn't be defined in a class if they can be
defined in a function etc. With C# it's even possible to go to the next
step, eg

void DoSomething()
{
string s;
if(SomeCondition())
{
s = GetMessage();
MessageBox.Show(s);
}
}

In this case s should probably be defined within the if.

Michael
 
"> But, there should be a ballance. For an example, if it's a
GlobalLogger, pass it as a param to every method is stupid.


Agreed. Every non-trivial application has several "global variables" which
need to find a home. For instance - a logger, an error handler, a set of user
options. I've never found an ideal solution to this problem. My current
preferred method is the singleton pattern, but it's kinda ugly (eg.
"Logging.Instance.Log("Error!")). But, passing these things around as
parameters, or instance variables on non-related classes", is ridiculous.

(and yes, I have contradicted what I said in my other post... I forgot about
these "global variables")
 
I've written many programs in c# of considerable size with many modules
calling c# dlls and I've yet to find a need for the so called global
variables. I always write my code such that it should be possible to
reuse any class without having to depend on other classes that contain
a global variable while the larger amount of code in that dependent
class really is irrelevent to other classes. This isn't always easy to
do. If there is however a variable or some data that you really need to
share among many diverse classes, just pass a reference to the data in
the class's constructor. There's nothing stupid about that.

But before you get global happy and start passing everything you
consider global as parameters, you need to first ask yourself whether
the data you are passing is part of a larger group of data. In other
words, could it belong as a property in a class and could a reference
to this class be passed instead? If you can pass class instances, that
is always the best solution. This encapsulates your code, makes your
method signatures compatible regardless how many more properties you
add later and keeps the method's signature clean.

Johann Blake
 
.... (eg. Logging.Instance.Log("Error!")).

You could reduce this to only Logging.Log("Error!") if you declare the
appropriate static method.
I usuallly do it this way, and also:
a) make the "global" variable Instance private.
b) create a public read-only property that encapsulates it.

Regards - Octavio
 
He insists I should not have any global variables, but instead passes them
from one method to the next. I think it's dumb. What's so bad about global
variables?
Although a global variable is temping, and seems simple to use, it is the
the worst thing you could do if you make a program that needs to scale and
becomes a big program. Big programs must be in modular design otherwise the
program gets too complicated to understand if global variables are spread
across the a few hunderds of thousands of souce code lines. And it also
gives raise to complex naming of that variable if you use a 100 global
variables.

Static variables inside a class is the best way to go. It is stupidly simple
to create but must also be used with caution.
The most dynamic way for future development is to create a class object and
pass on that pointer to every class or method that needs this.
 
Olaf said:
Although a global variable is temping, and seems simple to use, it is the
the worst thing you could do if you make a program that needs to scale and
becomes a big program. Big programs must be in modular design otherwise the
program gets too complicated to understand if global variables are spread
across the a few hunderds of thousands of souce code lines. And it also
gives raise to complex naming of that variable if you use a 100 global
variables.

Static variables inside a class is the best way to go. It is stupidly simple
to create but must also be used with caution.
The most dynamic way for future development is to create a class object and
pass on that pointer to every class or method that needs this.


My approach to solve the problem is using a Singleton App class that
encapsulates any globally available data in my apps. In my App class I
may have other Singlton members, properties or methods like so.

App.User.Id
App.Forms.Count
App.HomeDirectory
App.TempDirectory
App.Quit()
 
Hi,

There is a confusion about the Singleton pattern and a static class, even
as they look similar they solve different problems and should be used in
different escenarios.

In the case of a Logging facility most of the time you use a "static"
class, and there is nothing wrong in that, a Logging class is in general
Stateless. A method call does not change nothing outside of it.


Cheers,
 
Hi,

This is impossible in a language as C# , simply because there is no
possible to declare a global variable, all variables needs to exist inside a
class.
But even in this escenario you may have the same problems that with a global
variable. A singleton could be considered a global variable ( or globaly
accesible ) , since it can be accessed from anywhere in the system. If you
do not keep attention in how you implement it you end with similar problems
that a global variable.

When you use a Singleton , as you propose, you need to keep especial
attention to concurrency , Jon skeet has a very good article about this.

cheers,
 
My approach to solve the problem is using a Singleton App class that
encapsulates any globally available data in my apps. In my App class I
may have other Singlton members, properties or methods like so.

App.User.Id
App.Forms.Count
App.HomeDirectory
App.TempDirectory
App.Quit()

I do this too :-)
 
The following example is something to avoid...



namespace ConsoleApplication2

{

class Program {

static void Main( string[] args ) {

A a = new A();

}

}



class A {

static public int theAnswerToLifeAndEverything = 42; // <<<< sort of
global



public A() {

Console.WriteLine( "The answer: {0}", theAnswerToLifeAndEverything );

B b = new B();

}

}



class B {

public B() {

Console.WriteLine( "The answer: {0}",
A.theAnswerToLifeAndEverything );

A.theAnswerToLifeAndEverything = 54; // <<<< whoa!

}

}

}


--
Grace + Peace,
Peter N Roth
Engineering Objects International
http://engineeringobjects.com
Home of Matrix.NET
 
I think that I like this better than a few scattered singletons. Getting back
to the Logging example, then Logging would be a class, and I'd had a
singleton App which has a Logging property..

App.Logging.Log("Error!");

I'd be tempted to call it "Globals" rather than "App"..:))..but that might
be asking for trouble.

Javaman
 
thanks Octavio & Ignacio.... (Spanish names? :) )

As I said, I've never found an ideal solution to this problem. I've used
both of the things you suggest.

With regards to the static class method encapsulating the singleton,
(Octavio), the problem I had with that was the sheer number of wrappers that
were involved in getting to a the actual logging function. This was
especially painful as my "log" function was overloaded, and I was working in
C#, with .h & .cpp files. It would be simpler in C#

With regards to the static class method (not encapsulating a singleton)
(Ignacio), then I think you have a point. My current thinking is to always
use a class, and a Singleton pattern if necessary, partly for expandability,
in case we later discover the need for a class, but mainly for consistency -
the more I look at object oriented code, the more I expect everything to be
an object, and I just feel more comfortable with Singleton, than static
methods.
 
Olaf Baeyens said:
Although a global variable is temping, and seems simple to use, it is the
the worst thing you could do if you make a program that needs to scale and
becomes a big program. Big programs must be in modular design otherwise
the
program gets too complicated to understand if global variables are spread
across the a few hunderds of thousands of souce code lines. And it also
gives raise to complex naming of that variable if you use a 100 global
variables.

Just because having hundreds of global variable is bad doesn't mean that
having a few is bad. A singleton class really is just a different way to
handle global variables and the class itself is really just like a global.
The most dynamic way for future development is to create a class object
and
pass on that pointer to every class or method that needs this.

More trouble than it's worth in some cases, as with the example someone used
LogedInUserID, every class probably uses it but passing it around would be
messy.

Michael
 
The most dynamic way for future development is to create a class object
More trouble than it's worth in some cases, as with the example someone used
LogedInUserID, every class probably uses it but passing it around would be
messy.
I doubt that every class needs this.
If this is the case then something is wrong with your framework structure
and is probably created the C way instead of the C++ way. (C# in this case)

I know that LogedInUserID is just a simple example, but In my opinion you
must always be prepared for the future and you cannot predict what login and
security protocol will be needed. The code you create now will probably keep
on running for the next 5-10 years, so better to be prepared.

I do admit that at this point this seems to be overkill, but your code base
grows very fast and defining this LogedInUserID in a security class, makes
you code ready for the future, or at least make it easier to adapt.

A stupid example would be that you need to have a login for this server, but
imagine that your files are spread on a local server and a internet server.
Then you need 2 logings and maybe 2 user ID's.
 
Hi,


Javaman59 said:
thanks Octavio & Ignacio.... (Spanish names? :) )

Yes, I'm cuban
As I said, I've never found an ideal solution to this problem. I've used
both of the things you suggest.

I think that there is no ideal solution, at least not one that works
always, it's the experience what tell you what to use in each case.
With regards to the static class method encapsulating the singleton,
(Octavio), the problem I had with that was the sheer number of wrappers
that
were involved in getting to a the actual logging function. This was
especially painful as my "log" function was overloaded, and I was working
in
C#, with .h & .cpp files. It would be simpler in C#

With regards to the static class method (not encapsulating a singleton)
(Ignacio), then I think you have a point. My current thinking is to always
use a class, and a Singleton pattern if necessary, partly for
expandability.

You are ALWAYS using a class, what you mean is an "instance" , they are
different things.
True is that with a singleton you get more flexibility, at the cost of more
complexity, again the decision of which to use depends of the case at hand.

IMO the best example of a static class is Math , there is no point in making
it a singleton.
in case we later discover the need for a class,

As I said before both are classes, what are you refering to?
but mainly for consistency -
the more I look at object oriented code, the more I expect everything to
be
an object, and I just feel more comfortable with Singleton, than static
methods.

Are you refering to instances? if so you are not right, the static exist for
a reason, they are methods that are not associated with a particular
instance, some times they are the only way ( or the preffered way) to create
an instance of the class, a good example is IPAddress , it does have
several constructors, none of which takes a string like "XXX.XXX.XXX.XXX" ,
but you have IPAddress.Parse( string ) which return an IPAddress instance.


cheers,
 
Back
Top