Global variables

S

Sunil

Hi all,

I want to know how good or bad it is using global variables i.e
advantages
and disadvantages of using global variables.

Sunil.
 
U

Ulrich Eckhardt

Sunil said:
I want to know how good or bad it is using global variables i.e
advantages and disadvantages of using global variables.

Making variables as local as possible makes it easier to understand their
purpose. Sometimes a program consists of a handful of global objects
though, so it can't be said that they are always necessarily evil.

// consider this bad idea:
int i;
void bar( int xlim)
{
for( i=xlim; i>x/2; --i)
printf("bar(%d) i=%d\n", xlim, i);
}
void foo( int lim)
{
for( i=0; i!=lim; ++i)
bar( i*3);
}

Uli
 
A

Alexei A. Frounze

Ulrich Eckhardt said:
Making variables as local as possible makes it easier to understand their
purpose. Sometimes a program consists of a handful of global objects
though, so it can't be said that they are always necessarily evil.

There's another problem... If you want some function to work in a
multithreaded application (i.e. called from concurrent threads), that
function must not use any global variable but constant. Also, if you want to
use that function in a singlethreaded application but you want to use it
freely from different application parts w/o making them interact, then this
function must not use any global variables too. Any data must be passed to
such functions through a pointer. And the callers pass pointers to different
data to it. That way neither of the above mentioned problems will arise.
That's it.

Alex
 
E

Eric Sosman

Sunil said:
Hi all,

I want to know how good or bad it is using global variables i.e
advantages
and disadvantages of using global variables.

Pro: Globally-visible variables increase the "coupling"
between separately compiled modules of a program.

Con: Globally-visible variables increase the "coupling"
between separately compiled modules of a program.
 
K

Kenneth Brody

Alexei A. Frounze said:
There's another problem... If you want some function to work in a
multithreaded application (i.e. called from concurrent threads), that
function must not use any global variable but constant.

Not necessarily. While threads are beyond standard C, any system worth
its salt that supports threads will offer "thread-safe" methods of
accessing global variables.
Also, if you want to
use that function in a singlethreaded application but you want to use it
freely from different application parts w/o making them interact, then this
function must not use any global variables too. Any data must be passed to
such functions through a pointer. And the callers pass pointers to different
data to it. That way neither of the above mentioned problems will arise.

Typically, the reason or making such things global is to allow them to
interact. (That, and "it's not worth the overhead of passing it to every
function". Can you imagine a non-global stdout?)

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
A

Alexei A. Frounze

Kenneth Brody said:
Not necessarily. While threads are beyond standard C, any system worth
its salt that supports threads will offer "thread-safe" methods of
accessing global variables.

Right, there are all kinds of critical sections, mutexes, spinlocks,
semaphores, etc.
But that means that at any time only one thread can be executing a function
(or its part) protected thusly, which is not OK everywhere.
Typically, the reason or making such things global is to allow them to
interact.

But the interaction isn't always OK. We don't want race conditions, nor we
want something global be damaged by some other component using it at the
same time.
(That, and "it's not worth the overhead of passing it to every
function".

C++ carries that overhead everywhere, but what makes an application bad
isn't this small overhead that scales in a well-defined way, it's the bad
algorithms employed in the application :)
Can you imagine a non-global stdout?)

And while it doesn't necessarily has to be stdout, ability to separate some
input/output during testing and debugging is a good thing. Scaling to more
than one data processing channel needs this too. That's where some kind of
ID comes to play, be it a pointer (to data or function) or an integer
number. For instance, in an embedded system on my hardware I had only one
UART and one ADC/DAC. The code was written in such a way as to scale easily
for more data processing channels than just one which was allowed by my
limited hardware. The customer could develop his own PCB, put more I/O
circuitry to it and do that with this same software. So, who said stdout
ought to be one? There're many! :)

Alex
 
U

Ulrich Eckhardt

Alexei said:
C++ carries that overhead everywhere, but what makes an application bad
isn't this small overhead that scales in a well-defined way, it's the bad
algorithms employed in the application :)

What is this overhead in C++ you are talking about?

Uli
 
K

Kenneth Brody

Alexei A. Frounze said:

While highly OT for clc, C++'s "this" is only passed to object methods.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
J

John Bode

Sunil said:
Hi all,

I want to know how good or bad it is using global variables i.e
advantages
and disadvantages of using global variables.

Sunil.

File-scope (global) variables are rarely as useful as they seem, and
should be avoided.

The only reasonable time to use a global variable is when you need to
preserve state between function calls without exposing that information
to the caller. For example, take this simple stack module:

/* stack.c */

#define STACKSIZE 128

/**
* The static keyword is only there to
* prevent these symbols from being exported
* by the linker; the objects have static extent
* by virtue of being declared at file scope.
*/
static size_t stackPointer;
static int stack[STACKSIZE];

void Reset()
{
stackPointer = STACKSIZE;
}

void Push(int value)
{
if (stackPointer > 0)
stack[--stackPointer] = value;
else
/* handle overflow error */
}

int Pop()
{
int val;
if (stackPointer < STACKSIZE)
val = stack[stackPointer++];
else
/* handle underflow error */
}

int Top()
{
return stack[stackPointer];
}

In this example, the stack and stackPointer are used to keep track of
the stack contents between calls to Reset(), Push(), Pop(), and Top(),
and the stack user cannot manipulate these items directly.

This approach has several drawbacks, though. For one thing, you can't
create multiple stacks, since you only have one instance of stack data.
Secondly, and more importantly, it leads to maintenance headaches by
tightly coupling functions; in other words, changing the logic of one
function may have an unintended effect elsewhere if you change how the
global is manipulated. It can also make testing and debugging more
difficult.

If you need to preserve state, but don't want to expose that
information to whoever's using your module, you can hide it behind a
pointer to an incomplete type definition, like so:

/* stack.h */

#ifndef STACK_H
#define STACK_H

/**
* create a pointer to an incomplete type; this way,
* the use of the module can pass the pointer around, but
* cannot access the members of the struct through the pointer.
*/
struct stackData;
typedef struct stackData *stack_t;

/**
* Since the user of the module can only refer to a pointer
* to a stack, we need a way for him or her to create a new
* stack instance. NewStack() will dynamically create an
* instance of struct stackData and return the pointer to it.
*/
stack_t NewStack(size_t stackSize);
void Reset(stack_t stack);
void Push(stack_t stack, int value);
int Pop(stack_t stack);
int Top(stack_t stack);

/**
* Since we're dynamically allocating stacks, we need a way
* to release them as well.
*/
void DestroyStack(stack_t *stack);

#endif

/* stack.c */

#include <stdlib.h>
#include "stack.h"

/**
* Complete the struct type definition
*/
struct stackData {
size_t stackSize;
size_t stackptr;
int *stack;
} stackData_t;

/**
* Implement the functions, using the stack parameter.
* This is left as an exercise for the reader.
*/
 
P

pete

Sunil said:
Hi all,

I want to know how good or bad it is using global variables i.e
advantages
and disadvantages of using global variables.

I like to use them for profiling.
Then I remove them.
 
B

Baxter

If you have information, like a filename, that applies to the entire app and
may be used throughout the program, it should be a global.

In Palm programming, I find file-level globals to be very useful. They help
bring object-orientation to C. They should, however, be used only for that
data that is used by several functions. Note that in Palm programming, you
code functions that respond to messages.
 
M

Malcolm

John Bode said:
File-scope (global) variables are rarely as useful as they seem, and
should be avoided.

The only reasonable time to use a global variable is when you need to
preserve state between function calls without exposing that information
to the caller. For example, take this simple stack module:
Another case is where you have a huge dataset. For instance in 3d graphics
program you may have hard-coded a list of textures.
Technically you could make your image arrays (probably a few dozen with 64
by 64 24-bit values) local to main, and then pass them down. In practise
they are a lot better in file scope (textures.c), and maybe access functions
to retrieve them by id.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,169
Messages
2,570,920
Members
47,462
Latest member
ChanaLipsc

Latest Threads

Top