Summary of responses to: "Let ME try ..."
danny at itm.UUCP
danny at itm.UUCP
Thu Jun 7 04:33:34 AEST 1984
[In the immortal sounds of Don Martin: "Fwisk!"]
The comments I received were varied and plentiful. They ranged
from "fix ld to once again allow such" to "don't use globals at all".
Such extreams elude me, for I don't have source to ld, nor do I
wish to pass 14 variables to each and every function that needs
them.
There are a few rather innovative folks that do strange and
wonderous things with cpp, and another that uses the magic
of awk and make (boy, would I like to see the contortions that
could go through!).
Anyway, very brief summaries follow: remember I'm only a cerf,
so I may have left some replys out. If so, I apologize.
From: spuxll!ech (Ned)
...
You are right: it feels, smells, sounds, looks, and tastes like a hack (sure
glad I didn't step in it), cuz it are one. The correct solution is to tear
the lid off ld and put it back the way it was.
From: uvacs!jnw (Joe Wilson)
in reference to the "trick" of using the <#define extern> etc.,
I don't think it's a hack. I think it is something that everyone who stays
around c long enough eventually figures out or finds out. I like it and I use
it.
From: Bob English <ihnp4!ucbvax!lcc.bob at UCLA-LOCUS.ARPA>
Actually, if the variables are uninitialized, the "extern" is unnecessary.
In other words, a header file that reads:
int foo;
char *bar;
is fine, but one that reads
int foo = 1;
char *bar = "hi there chum";
is a no-no.
From: Steve Woods <ihnp4!ucbvax!cepu!scw at UCLA-CS.ARPA>
...
Remember please that there are hacks and there are hacks. Some hacks
are nasty and crude, and no self-respecting programmer would admit to
having committed them. Other hacks are nifty and elegant and provide
a touch of POSH and class to one's code; these haques are items of
pride to good programmers and are caried around in one's wallet and
show, with inordnate pride, to anyone who will stand still long enough.
From: David Chase <ihnp4!ucbvax!rbbb at rice.ARPA>
Sure it's a hack, and I do it all the time, a little differently. Instead of
# define extern
# include "foo.h"
# undef extern
I use the string "EXTERN", with include files starting
# ifndef EXTERN
# define EXTERN extern
# endif
and the main file containing "# define EXTERN". I prefer this, because
this way I don't have code that LOOKS like vanilla C, but isn't.
From: Michael B McIlrath <ihnp4!ucbvax!MBM at MIT-XX.ARPA>
I do
#ifdef EXTERNALS
#define external /* */
#else
#define external extern
#endif
Then I put the global variables in an include file that everybody
uses, using the modifier "external". Then I #define EXTERNALS at
the beginning of exactly one file.
From: allegra!rlgvax!umcp-cs!chris
My {\it favourite} way to deal with that, is merely not to deal with it...
...
Seriously, I wish more people understood the idea of ``BSS zero storage'';
then one wouldn't need such tricks.
>From hocda!grt (George Tomasevich)
Concerning multiply defined externals, I have been using the two-file method.
One certainly finds out soon enough if one forgets to add new externs
to the include file. As far as I know, 'lint' tells you if there are any
extraneous variables, but not if there are extraneous extern declarations.
I had not seen that '#define extern' hack, but would like to see a better way.
George Tomasevich, AT&T-BL
From: nw (Neil Webber) <allegra!vaxine!nw>
One way, which may be only slightly better than "#define extern" is to
put the following code in the ".h" file:
#if DEFINE_GLOBALS
#define global
#else
#define global extern
#endif
Then say "global int foo" instead of "extern int foo" in the .h file.
The main program says:
#define DEFINE_GLOBALS 1
#define "globals.h"
From: allegra!jpl (John P. Linderman)
... We adopted the following artifice to simplify
maintenance of code that included external variables in .h files.
If the include file used to look like
int i;
char foo[] = "bar";
we would replace them with
#ifdef OWNER
#define EXTERN
#define EXTINIT(X) = X
#else
#define EXTERN extern
#define EXTINIT(X)
#endif OWNER
EXTERN int i;
EXTERN char foo[] EXTINIT("bar");
In the makefile, we would then include a -DOWNER flag in exactly one
cc line, usually the one for the main routine. This made it easy to
get programs working again without having to duplicate headers or
rewrite code.
...
From: damonp at daemon.UUCP
What I have eventually come up with is the following. I am
not entirely satisfied with it, but it works ok. I tried the
# define extern route, but was unable to provide initialisers.
===extern.h=====
/*
* common external definitions
*/
#define EXTERN_IT
#include "extern.c"
====extern.c====
/*
* external definitions
*/
#ifndef EXTERN_IT
# include "dclass.h"
# undef ev
# define ev(type, var, init) type var = init
#else
# undef ev
# define ev(type, var, init) extern type var
#endif
ev(char *, usage, "dclass {Machine=<mach> | [Class=]<class>}");
ev(char *, mach, 0); /* desired machine */
ev(char, home[MAX_PATH+1], 0); /* home directory */
ev(char, verbose, 0); /* verbose flag */
From: ihnp4!ucbvax!DEPSTEIN at BBNG.ARPA (David A. Epstein)
Personally, I usually make an "awk" script that generates the .h file from
the .c file and then put a dependency line in my Makefile to the following
effect:
foo.h : foo.c
awk -f awk.script foo.c > foo.h
Illegitimum non Carborundum
[Editor's note: what?]
--
Daniel S. Cox
(akgua!itm!danny)
More information about the Comp.unix.wizards
mailing list