[net.unix-wizards] new topic...exorcising externs

jpl@allegra.UUCP (John P. Linderman) (06/08/84)

There are a number of situations where externals are both cleaner and
more convenient than parameter passing.  One instance that comes to mind
is "errno".  I wouldn't hold it up as the paradigm of clean design,
but it beats passing a pointer to an error value to every system call.
Another favorite of mine is to declare an external
    char *Progname;
and then do
    Progname = argv[0];
or
    Progname = p = argv[0];
    while (*p) if (*p++ == '/') Progname = p;
in the main routine to set Progname to the name (or basename) of the
command as it was invoked.  Being external, the name is available to
diagnostic routines without having to be passed around.  This eliminates
the problems of building the command name into the command (suppose it
gets linked or installed under a different name) and encouraging the
use of the command name in all error diagnostics (don't you just love
it when you run a pipeline of commands and one of them prints:
    malloc failed.
and then dies without identifying itself?  It would almost be better
if it missed the check and dropped a core, so you could run a "strings"
on the core and find out who it was.)

John P. Linderman  Department of External Affairs  allegra!jpl

andrew@orca.UUCP (Andrew Klossner) (06/09/84)

[]

	"There are a number of situations where externals are both
	cleaner and more convenient than parameter passing.  One
	instance that comes to mind is "errno".  I wouldn't hold it up
	as the paradigm of clean design, but it beats passing a pointer
	to an error value to every system call."

The "well structured" approach would be to define a small module (aka
package) with entry points as follows:

	void seterrno(i) int i;

		/* called by system routines to record an error number */

	int geterrno()

		/* returns the last parameter to seterrno, 0 if none */

Now you do your system calls as follows:

	if (open(...) == -1) {
		printf("open error %d\n", geterrno());
		}

Presto, no externals, just a single static within the errno module.
This would make a lot more sense if the loader supported more than just
a flat global name space, a la Modula II.

  -- Andrew Klossner   (decvax!tektronix!orca!andrew)      [UUCP]
                       (orca!andrew.tektronix@rand-relay)  [ARPA]

henry@utzoo.UUCP (Henry Spencer) (06/10/84)

I agree that "progname" for error-message purposes is a good use of
externs.  I am less happy about "errno" -- it's a kludge around the
problem of sometimes wanting specific error information and sometimes
not, and having problems fitting this into the classical return-value
paradigm -- but agree that we are stuck with it.

However, if those are the best examples people can come up with for
good uses of external variables, I think my contention (that external
variables are usually bad) is fairly safe.  These are a drop in the
bucket, folks, accounting for practically 0% of the use of external
variables.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry