[comp.lang.c] An Ethics Question

jeff@uop.edu (Jeff Ferguson) (04/07/89)

	Here's a pretty basic ethics question: how do the mighty C
programmers in netland have to say about global variables?  Take,
for example, the following two pieces of (idiotically simple) code:

/********* Example 1 **********/

FILE *fp;

main()
{
	/* code */
}

readfile()
{
	/* code */
}

/******** End Of Example 1 *********/

/******** Example 2 **********/

main()
{
	FILE *fp;

	/* code */
}

readfile(fp)
{
	/* code */
}

/******* End Of Example 2 ********/

Global variables or passed parameters?  I'm anxiously awaiting the pros
and cons of this issue.  Thank you.


--
Jeff Ferguson		       ...!{ucbvax|lll-crg}!ucdavis!uop.edu!jeff
Computer Science Department    ...!cepu!retix!uop.edu!jeff
University of the Pacific      jeff@uop.edu	(209) 944 - 7105

"My father to the left of me, my mother to the right,
 Like everyone else they're pointing, but nowhere feels quite right"
					-- Genesis

gwyn@smoke.BRL.MIL (Doug Gwyn ) (04/07/89)

In article <1819@uop.edu> jeff@uop.edu (Jeff Ferguson) writes:
>Global variables or passed parameters?

Structured programming methodology argues for parameters.
There are some applications for which this can get horribly
out of hand, so rather than follow any rule blindly, I try
to parameterize unless it is obviously going to cause a problem.

kenj@pyramid.pyramid.com (Ken McDonell) (04/07/89)

In article <1819@uop.edu> jeff@uop.edu (Jeff Ferguson) writes:
>
>	Here's a pretty basic ethics question: how do the mighty C
>programmers in netland have to say about global variables?
[ example deleted ]

Whenever there is a choice (and for real examples this is not always
the case, e.g. you probably don't want to cart around global flags
such as "debug on or off?" via arguments to every procedure), local
variables are generally preferred.  Because ...

1. Better software engineering (a la information hiding and object
   orientied philosophies)

2. Better performance for scalar variables (giving the compiler a
   chance at local register allocation to avoid memory references
   is typically a bigger gain than any additional overhead on the
   procedure call/return).

1. is always a truism.  2. depends on other coding style issues,
data structure details and usage dynamics.

>for example, the following two pieces of (idiotically simple) code:
>
>/********* Example 1 **********/
>
>FILE *fp;
>
>main()
>{
>	/* code */
>}
>
>readfile()
>{
>	/* code */
>}
>
>/******** End Of Example 1 *********/
>
>/******** Example 2 **********/
>
>main()
>{
>	FILE *fp;
>
>	/* code */
>}
>
>readfile(fp)
>{
>	/* code */
>}
>
>/******* End Of Example 2 ********/
>
>Global variables or passed parameters?  I'm anxiously awaiting the pros
>and cons of this issue.  Thank you.
>
>
>--
>Jeff Ferguson		       ...!{ucbvax|lll-crg}!ucdavis!uop.edu!jeff
>Computer Science Department    ...!cepu!retix!uop.edu!jeff
>University of the Pacific      jeff@uop.edu	(209) 944 - 7105
>
>"My father to the left of me, my mother to the right,
> Like everyone else they're pointing, but nowhere feels quite right"
>					-- Genesis

steve@umigw.MIAMI.EDU (steve emmerson) (04/07/89)

I differentiate "global" variables into two types: "external" and "static".
Just like their namesakes, external global variables are visible outside
the compilation unit (file) in which they're defined whereas static
global variables (an oxymoron? ;-) can be easily referenced only from within 
the compilation unit.

I use external global variables *very* rarely.  I sometimes use static
global variables, rather than argument passing, from within a compilation
unit, even when strictly unnecessary.  If the unit is small enough, the
conceptual problems are small: about the same as the speed gain.  It's
a toss-up.
-- 
Steve Emmerson                     Inet: steve@umigw.miami.edu [128.116.10.1]
SPAN: miami::emmerson (host 3074::)      emmerson%miami.span@star.stanford.edu
UUCP: ...!ncar!umigw!steve               emmerson%miami.span@vlsi.jpl.nasa.gov
"Computers are like God in the Old Testament: lots of rules and no mercy"

henry@utzoo.uucp (Henry Spencer) (04/08/89)

In article <1819@uop.edu> jeff@uop.edu (Jeff Ferguson) writes:
>Global variables or passed parameters?  I'm anxiously awaiting the pros
>and cons of this issue.  Thank you.

Parameters are generally better than global variables.  The more restricted
scope gives less opportunity for other parts of the program to modify them
in surprising ways, and the explicit presence in the parameter list makes
it easier to remember who uses what.

Efficiency considerations can go either way, depending on the machine,
although one significant issue is it's generally harder for compilers to
know when it's safe and desirable to put global variables in registers.
On almost any machine, the code will run a good deal faster if heavily-
used variables are in registers.

The down side is that it can be a royal pain passing parameters down
through multiple layers of functions just because they're needed at the
lowest level.  This is especially true if they're used for things like
error reporting that are peripheral to the function's intended purpose;
then the clutter in the argument list obscures the real meaning.  For
this sort of thing, global variables are probably better.

Almost anything that relies on global variables is problematic in the
presence of multiple processes within the same address space (aka threads).
-- 
Welcome to Mars!  Your         |     Henry Spencer at U of Toronto Zoology
passport and visa, comrade?    | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

pjs269@tijc02.UUCP (Paul Schmidt ) (04/10/89)

> Global variables or passed parameters?  I'm anxiously awaiting the pros
> and cons of this issue.  Thank you.

There is a proper way of doing global variables in C programming that is
supported by a design methodology.  In the paper "Two-Dimensional Program
Design," by Shmuel Rotenstreich and William E. Howden, in IEEE 
Transactions on Software Engineering, Vol. SE-12, No. 3, March 1986, the
authors describe a modification of structured design techniques that can
be easily implemented in C only by global variables.  They contend that
it is wasteful and more confusing to pass variables from lower level
routines through higher level routines and back to lower level routines
with the higher level routine never using it.

The use of "static" also helps to hide the variables from the higher level
routines so that no higher level routine can ever use these variables.

gharris@secola.Columbia.NCR.COM (Buddie Harris) (04/11/89)

In article <227@umigw.MIAMI.EDU> steve@umigw.miami.edu.UUCP (steve emmerson) writes:
>Steve Emmerson                     Inet: steve@umigw.miami.edu [128.116.10.1]
>"Computers are like God in the Old Testament: lots of rules and no mercy"

Shouldn't we progress the computer to be more like Jesus in the New Testatment:
Guidelines and lots of mercy.


-- 
------------------------------------------------------------------------------
! Sleep well and dream of large women.  -  The Dread Pirate Roberds          ! 
! gharris@secola.Columbia.NCR.COM (George Harris)  Have a nice day :-)       !
------------------------------------------------------------------------------

cik@l.cc.purdue.edu (Herman Rubin) (04/13/89)

In article <1989Apr7.190827.4289@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes:
> In article <1819@uop.edu> jeff@uop.edu (Jeff Ferguson) writes:
> >Global variables or passed parameters?  I'm anxiously awaiting the pros
> >and cons of this issue.  Thank you.
> 
> Parameters are generally better than global variables.  The more restricted
> scope gives less opportunity for other parts of the program to modify them
> in surprising ways, and the explicit presence in the parameter list makes
> it easier to remember who uses what.
> 
> Efficiency considerations can go either way, depending on the machine,
> although one significant issue is it's generally harder for compilers to
> know when it's safe and desirable to put global variables in registers.
> On almost any machine, the code will run a good deal faster if heavily-
> used variables are in registers.

			..........................

Why is it necessary to use one or the other?  Consider the following
highly recursive program, which is a fairly quick way of simulating
the number of heads in n tosses of an honest coin.  Please excuse minor
C syntax errors.

external arrays and variables and #includes
coin(n)
int n;
{
SETUP
int m;
m = cn(n);
RESTORE
return m;
}
cn(n)
int n;
{
int k:
if(ODD(n))k=BIT;
else k=0;
n >>= 1;
if (n == 0) return k;
return (k + cn(n) + 2*cn(n-cn(n)));
}

Now SETUP and BIT can be done in many ways; it is even possible to use 
globals outside of the recursion and no fixed registers, but this involves
many memory references at each stage.  On the VAX, the best procedure I have
come up with uses 5 registers, but the recursion passes only one number, and
the average number of memory reference per use of BIT is <0.02.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)

ok@quintus.UUCP (Richard A. O'Keefe) (04/14/89)

>Global variables or passed parameters?  I'm anxiously awaiting the pros
>and cons of this issue.  Thank you.

There are lots of good books which explain the reasons why global
variables are frowned on and what the alternatives are.  Ledgard and
Tauer, "Professional Software, Vol 2, Programming Practice" is one I
like.  One thing to note is that C hasn't _got_ most of the
alternatives (though 'static' variables are a help).

I try to arrange my programs so that any chunk which looks as though it
might be useful later on can be pulled out as a self-contained "module".
Even when writing filter programs, I write them as functions called
from main with stdout and (stdin or whatever the command line arguments
asked for) as arguments, so that if I ever have a use for that filtering
operation in an O/S which doesn't support popen() -- can you say CMS? --
I can just pick it up and use it.

What the big names in software engineering are really worried about is
not global variables as such, but the nasty messes you can get in when
part of your program has a _hidden_ communication channel with another
part.  Just by looking at a function call, you cannot tell what it might
be using, and worse, what it might be changing.  UNIX's "cxref" tool is
a help, but it could be a lot more helpful.  (Dear old B6700 Algol, sob.)

emuleomo@surfers.rutgers.edu (Emuleomo) (04/17/89)

>
> Global variables versus parameter passing
>
What I HATE about global variables is that the first time you look at
a function that uses it, the functions seems to work mysteriously.
Futhermore, you had better be damned sure that you dont 'tamper' with those
variables since they could also be used somewhere else (in another function).

The RULE OF THUMB is...
PASS PARAMETERS whenever you can. Believe me. It will save you countless
hours of debugging time.  Besides they make your functions transportable.
However, I must admit that if you find yourself passing say 10 parameters
to a function and maybe half of them are the addresses of variables 
into which you want to assign values, then you may consider using 
global variables.  Howvever, try to keep all the routines that need to 
communicate with each other via global variables in the same file and declare 
the variables as STATIC. 
Another helpful trick is make the Fisrt letter of your Global Variable
UPPERCASE and the rest lowercase!. This way, you can easily identify
which are the global variables in your code!

--Emuleomo O.O.
** The only global variable I use is a database! **
lowercase letters EXCEPT the f
you want their values
My first reaction in coding a function/subroutine is to pass parameters
to it and let it operate on these parameters.
If you are working on a large and complex so