To use global variables or no????

E

eoindeb

Sorry to ask another global variable question, but from reading other
posts I'm still not sure whether to use them or not.

I have a program with a set function that calls 4 other functions in
order - let's say function A, B, C, D.

It always calls function A first which is a function that returns a
system path. Now all other functions require that variable as well
(function A returns a char pointer)

So my question is - should I declare a global variable, set it's value
using function A and then use that variable in the other functions as
well.

Or is there a preferred method to achieve what I need? Hope I have made
myself clear!!

Thanks.
 
V

Vladimir Oka

eoindeb said:
Sorry to ask another global variable question, but from reading other
posts I'm still not sure whether to use them or not.

I have a program with a set function that calls 4 other functions in
order - let's say function A, B, C, D.

It always calls function A first which is a function that returns a
system path. Now all other functions require that variable as well
(function A returns a char pointer)

So my question is - should I declare a global variable, set it's value
using function A and then use that variable in the other functions as
well.

Or is there a preferred method to achieve what I need? Hope I have made
myself clear!!

If I understand correctly, you have one function, say F, that calls
functions A, B, C, and D in order. Function A provides input value for
the other three. I don't see why you should worry about global (file
scope) variables. Just declare a local variable in function F, and use
it to collect return value of A, and pass it to B, C, and D. Such a
variable is not global, although it is used in more functions.

Still, using variables external to the function may not be a good idea,
as looking at the function call it is not immediatelly obvious what are
the inputs, and outputs. You don't have a clean interface, you
introduce (and use) side effects.

As always, global variables do have their uses, but that has to be
judged on a case by case basis. I don't think you provide enough
information about yours to make a good guess.
 
F

Fred Kleinschmidt

eoindeb said:
Sorry to ask another global variable question, but from reading other
posts I'm still not sure whether to use them or not.

I have a program with a set function that calls 4 other functions in
order - let's say function A, B, C, D.

It always calls function A first which is a function that returns a
system path. Now all other functions require that variable as well
(function A returns a char pointer)

So my question is - should I declare a global variable, set it's value
using function A and then use that variable in the other functions as
well.

Or is there a preferred method to achieve what I need? Hope I have made
myself clear!!

Thanks.

One problem with global variables is that it is difficult to see where
those variables get changed. For example:

char *str;
int n = 1;

void func1() {
str = (n==1)? "hello" : "bye";
fun2();
fun3();
fun4();
fun5();
/* what are the values of n and str here ? */
The answer to the above question is: i have to examine
the code in fun2, fun3, fun4, and fun5, because I don't know
who might modify the global variables.

If you have a lot of variables that are common to several
of the functions, you can pass them all throught the call,
or you can set up a struct that contains all of the shared
variables, and just pass that struct around.

/* define struct MyStruct */
....

Then:
void func1() {
struct MyStruct s;
/* Fill in initial values */
...
fun2();
fun3(&s);
fun4();
fun5(&s);

Now I know that I only have to examine fun3 and fun5
to find possible changes to the variables.
 
R

Richard Heathfield

eoindeb said:
Sorry to ask another global variable question, but from reading other
posts I'm still not sure whether to use them or not.

First Rule of Global Variables: Don't use them.

Second Rule of Global Variables (for experts only): Don't use them *yet*.
Or is there a preferred method to achieve what I need? Hope I have made
myself clear!!

Parameters.
 
J

John Bode

eoindeb said:
Sorry to ask another global variable question, but from reading other
posts I'm still not sure whether to use them or not.

I have a program with a set function that calls 4 other functions in
order - let's say function A, B, C, D.

It always calls function A first which is a function that returns a
system path. Now all other functions require that variable as well
(function A returns a char pointer)

So my question is - should I declare a global variable, set it's value
using function A and then use that variable in the other functions as
well.

Or is there a preferred method to achieve what I need? Hope I have made
myself clear!!

Pass the result of A to B, C, and D as a parameter:

char *path = A();
B(path);
C(path);
D(path);

There are several reasons why you don't want to use a global. First of
all, you won't be able to reuse B, C, or D in another module where that
global isn't defined. Secondly, your code won' t be thread-safe; If
one thread can call A and change the value of the global while another
thread is executing B, C, and D, you'll run into problems. Globals
introduce maintenance headaches; there are few things worse than
finding a bug that's due to two different pieces of code using the same
global for different reasons.

Generally speaking, you want to write your functions so that all the
information they need to do their job is provided in the parameter
list. There are times where you need to preserve state between
function calls (such as the position of a stack pointer in a stack
module), but even that can be written in such a way that the state
information is passed as a parameter, instead of stored in a global.

If you're working in an environment where stack space or register space
is at a premium and the overhead of passing a parameter is causing real
problems, then using a global is justified, but that's a fairly
specialized domain. In those cases, you'll *know* whether using a
global is the right thing to do or not.
 
A

Andrew Poelstra

eoindeb said:


First Rule of Global Variables: Don't use them.

Second Rule of Global Variables (for experts only): Don't use them *yet*.


Parameters.
Regarding my earlier posts that seemed to concone global variables:

I wondered why the functions that changed my globals never confused
me; it turned out that I had been habitually passing variables by
parameter, even those that were global.

In conclusion, I moved all my globals to local scope and the code
continued to compile just fine. Lesson learned. There is virtually
never a need for globals.
 
D

Dann Corbit

Andrew Poelstra said:
Regarding my earlier posts that seemed to concone global variables:

I wondered why the functions that changed my globals never confused
me; it turned out that I had been habitually passing variables by
parameter, even those that were global.

In conclusion, I moved all my globals to local scope and the code
continued to compile just fine. Lesson learned. There is virtually
never a need for globals.

stdin
stdout
stderr
are globals.
 
M

Malcolm

eoindeb said:
Sorry to ask another global variable question, but from reading other
posts I'm still not sure whether to use them or not.

I have a program with a set function that calls 4 other functions in
order - let's say function A, B, C, D.

It always calls function A first which is a function that returns a
system path. Now all other functions require that variable as well
(function A returns a char pointer)

So my question is - should I declare a global variable, set it's value
using function A and then use that variable in the other functions as
well.

Or is there a preferred method to achieve what I need? Hope I have made
myself clear!!
As a general rule, don't use global variables.
It introduces a dependency, which means that the function only works if its
parameters are correct, and the global is set up correctly. This is hard for
a human to achieve.

However there are some exceptions. For instance if a function is called
indirectly, like the comparison to qsort, and needs state information to do
its stuff, it is alot easier to just use a global rather than try to set up
some scheme whereby the pointer is attached to the sort structures.

Another one is recursive functions which take a lot of parameters. Because
the function may call itself thousands of times, often it is worth while
separating out the constant parameters that don't change during the
recursion, to avoid unnececcary stack set ups.

Don't be afraid of passing a parameter down three or four levels to where it
is used, however. Often that makes perfect sense.
 
A

Andrew Poelstra

stdin
stdout
stderr
are globals.

Not sure why I have to say this, but I meant /user-defined/ globals.

Also, those aren't necessarily globals. They could be macros or some
other esoteric creature. (Unless the Standard says otherwise. Anyone?)
 
R

Richard Heathfield

Andrew Poelstra said:
Not sure why I have to say this, but I meant /user-defined/ globals.

It's always best to say what you mean. This is almost certainly Dann's
point. Obviously you're quite new to the group and I don't know very much
about you (e.g. I don't know how old you are, and there's no reason why I
should), but if you're reasonably young it is probably true that Dann has
been writing C programs since before you were born. He knows his stuff.
Listen to Dann. Listen to Dann. He is, so to speak, one of the droids
you're looking for.

Incidentally, the term "global" is very woolly. It's best to refer to the
scope and linkage of objects rather than relying on everyone guessing that
you mean what they mean by "global".
Also, those aren't necessarily globals. They could be macros or some
other esoteric creature. (Unless the Standard says otherwise. Anyone?)

They are expressions of type "pointer to FILE". If they didn't have file
scope and external linkage, they'd be effectively unusable. It is therefore
not unreasonable to call them "globals", since they're about as global as
anything in C gets.
 
O

Olivier Galibert

In conclusion, I moved all my globals to local scope and the code
continued to compile just fine. Lesson learned. There is virtually
never a need for globals.

You're not an expert yet ;-)

File-scope globals, aka statics, are extremely useful. Think for
instance of a variable with a verbosity level, you don't want to pass
that level everywhere you may want to print a debugging message. Or a
memory manager. In practice, any module which has state but for which
it would become quickly inconvenient to pass struct pointers around
all the time.

Program-level globals tend to be more useful in C++ than C, for
everything that is used a lot and happens to be a singleton. In C++ a
global object is nice, and you hide the functions as class methods.
In C OTOH you make the functions global and hide the state in statics.
I can't imagine cases where a full-on global seems the right method in
C, except for the cases where your module is too big to fit in one
source file.

OG.
 
A

Andrew Poelstra

Andrew Poelstra said:

It's always best to say what you mean. This is almost certainly Dann's
point. Obviously you're quite new to the group and I don't know very much
about you (e.g. I don't know how old you are, and there's no reason why I
should), but if you're reasonably young it is probably true that Dann has
been writing C programs since before you were born. He knows his stuff.
Listen to Dann. Listen to Dann. He is, so to speak, one of the droids
you're looking for.

Thanks; it's always nice to find new teachers. You're probably right about
him coding since before I was born. Few regulars here started programming
after '91. ;-)
Incidentally, the term "global" is very woolly. It's best to refer to the
scope and linkage of objects rather than relying on everyone guessing that
you mean what they mean by "global".

I generally mean file scope, but I can see why others would have different
meanings.
They are expressions of type "pointer to FILE". If they didn't have file
scope and external linkage, they'd be effectively unusable. It is therefore
not unreasonable to call them "globals", since they're about as global as
anything in C gets.

True, but FILE could be a macro. (That was my line of thinking, anyway). I
just realized that you can't have a pointer to something unnatural, so I
was wrong.
 
D

Dann Corbit

Jack Klein said:
No, they're not, they're macros.

True, but they must resolve to type pointer to file:

Page 262:
stderr
stdin
stdout
which are expressions of type ''pointer to FILE'' that point to the FILE
objects
associated, respectively, with the standard error, input, and output
streams.
Long time, Dann. How the heck are you?

Peachy-creamy with a cherry on top, as usual.
 
J

jaysome

eoindeb said:


First Rule of Global Variables: Don't use them.

The C Standard really makes no mention of "Global Variables". I hope
that what you are referring to as "Global Variables" are variables
visible to two or more translation units, e.g.:

// foo.h
extern int iBar;

and not file scope variables, e.g.:

// foo.c
static int iBar;
 
D

Dann Corbit

jaysome said:
The C Standard really makes no mention of "Global Variables". I hope
that what you are referring to as "Global Variables" are variables
visible to two or more translation units, e.g.:

// foo.h
extern int iBar;

and not file scope variables, e.g.:

// foo.c
static int iBar;

If variable iBar could be an auto, then this is a mistake (as you probably
know, but I am emphasizing it).

The general rule of thumb is that scope should be minimized.
Make a variable auto, if it does not have to be static.
Make a variable static, if it does not have to be extern.
Make a variable extern if there is no other way (e.g. a file handle that
everyone will have to be able to use directly like stdin.)

Besides the greatly simplified debugging, you will be very happy when it is
time to make a threaded version. Yes, I know. C has no concept of threads.
But you will probably have to write a threaded version eventually,
nevertheless. If you used nothing but auto variables (and if any static
variables are const), then the threaded version is the same as the
non-threaded version.
 
K

Keith Thompson

Jack Klein said:
[...]
stdin
stdout
stderr
are globals.

No, they're not, they're macros.

So it would seem, but I wonder if that was the intent.

C99 7.19.1 says:

The header <stdio.h> declares three types, several macros, and
many functions for performing input and output.

...

The macros are NULL (described in 7.17);

...

stderr
stdin
stdout

which are expressions of type "pointer to FILE" that point to the
FILE objects associated, respectively, with the standard error,
input, and output streams.

For all the other macros, the standard says "which expands to ...";
for stderr, stdin, and stdout, it says that they *are* expressions.
And I can't think of any good reason why an implementation couldn't
declare them as global objects rather than as macros (except of
course, that a program can tell the difference using #ifdef).

Off to comp.std.c.
 
R

Richard Heathfield

jaysome said:
The C Standard really makes no mention of "Global Variables".

As I keep telling people, except that I thought nobody ever listened.
Perhaps someone finally did.
I hope
that what you are referring to as "Global Variables" are variables
visible to two or more translation units,

No, I'm talking about non-const objects that are not auto objects.
e.g.:

// foo.h
extern int iBar;

and not file scope variables, e.g.:

// foo.c
static int iBar;

Now try to come up with a plausible reason why a good programmer would need
this static int.

I can think of two reasons off-hand for using non-auto non-const objects,
one of which I don't like but am prepared to accept, and the other of which
I don't like but don't have any choice about accepting.
 
J

John Devereux

Richard Heathfield said:
I can think of two reasons off-hand for using non-auto non-const objects,
one of which I don't like but am prepared to accept, and the other of which
I don't like but don't have any choice about accepting.

I might be misunderstanding you, but don't some types of function need
to keep "static" state information? E.g. functions like malloc?
 
A

Al Balmer

I might be misunderstanding you, but don't some types of function need
to keep "static" state information? E.g. functions like malloc?

I may also be misunderstanding, but I often find static objects useful
when writing access functions for opaque types.
 

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

No members online now.

Forum statistics

Threads
474,183
Messages
2,570,969
Members
47,524
Latest member
ecomwebdesign

Latest Threads

Top