Global variables! Where do i use them

I understand the concept of global variables and how to create one, but the programmers philosophy that has been passed around that globals are evil and make ones code hard to read.

I understand that globals can be useful in some ways, but im not sure how, what is better? Should i keep passing a parameters around my functions ( and having to type out that parameter each time i reuse a function ) or should i use a global?

I have looked at some other forums and i am very confused of how i should set out my code.

Many Thanks!
You use global variables when you're calling a function and need a variable (or variables) to put in its arguments. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

// GLOBAL VARIABLES

int x, y;

// GLOBAL VARIABLES

int add(int num1, int num2)
{
    cout<<(num1 + num2)<<endl;
}

int main()
{
    add(x, y);
    return 0;
}


You could use the global variables for a minus function as well, if it had the same arguments. This means that you can declare only a few variables and use them on many functions (which is why they're called global variables).
closed account (zb0S216C)
SuperStinger wrote:
"...the programmers philosophy that has been passed around that globals are evil and make ones code hard to read."


The Problems


That depends on the complexity of the program and how you use those variables/objects. Global variables/objects are not bad, it's the way programmers use them which gives them a bad name. Generally speaking, global variables/objects are considered bad practice because:

● ...it's easy to form a function that directly refers to a global storage which means the function depends on a global variable/object to function. Removing the latter dependency can break the function.

● ...global storage is scoped to an invisible name-space. There's no structure to them; therefore, ambiguities can arise when you least expect it. Consider this:

1
2
3
4
5
6
7
8
9
10
11
12
// Global Name-Space:
int Data_;

struct Structure
{
    int Data_; // OK. Data_ is scoped to Structure.

    int GetData( ) const 
    {
        return( Data_ ); // A
    }
};

In the above code, the line marked "A" is ambiguous to us programmers. Why? Because the scope of global storage is always resolved implicitly. Because the identifier of the global storage and the data-member are the same -- hence the ambiguity -- the compiler may choose the data-member. However, we may not want that to happen; we may want the global storage instead (unlikely). To resolve this, we have two choices:

A) Use the "this" pointer:

1
2
3
4
int GetData( ) const 
{
    return( this->Data_ );
}

or...

B) Use the scope-resolution operator on the global storage:

1
2
3
4
int GetData( ) const 
{
    return( ::Data_ );
}

However, using global storage within any function -- irrespective of scope -- causes the function to depend on that global storage as I've said before.

● ...and for the final reason, the destruction of a global object must happen after all other objects are destroyed. While this may not be a problem in some cases, it can be a pain in others.

The Resolution


The issue of global storage will always be around. The only thing you can do is:-

● ...resist the urge to write classes and functions that directly refer to a global variable/object and pass them by reference or value instead, or...

● ...begin an identifier with the scope-resolution operator to explicitly indicate that the identifier is within the global name-space and should not be changed. Then again, even this doesn't protect your code from code-breaking changes.

Note: Functions that depend on global storage marks the function's author a novice.

Wazzak
Last edited on
> Should i keep passing a parameters around my functions
> ( and having to type out that parameter each time i reuse a function )
> or should i use a global?

Depends. How many lines of code does your program have?

A couple of hundred lines in two files? Merrily use global variables; they are just fine.

Ten thousand lines in a hundred files? As far as possible, avoid global variables with external linkage. If you just have to have them, put them in a namespace (a la std::cout). A global variable in an anonymous namespace (not programatically visible outside the translation unit) in a hundred line implementation file is still just fine.

Its not just variables; the principle applies to types and functions too. In general, restrict the programatic visibility of any entity to the smallest scope in which it is required.
softwaretime: Thank you for your effort, but you didnt answer the question! >_<

Framework: A very helpful, structured response with dot-pointed awesomeness and subheadings, this really helped me and i appreciate you doing this for me.

JLBorges: A short and concise answer that solves the problem quickly, I like to plan a little before writing my program, so i havent actually wrote it yet, i just dont want to restructure an entire program half way through!

Thanks for your respones, all help is much appreciated
Topic archived. No new replies allowed.