[comp.lang.c] C common practice.

jlg@cochiti.lanl.gov (Jim Giles) (04/23/91)

In article <15904@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) writes:
|> In article <21964@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
|> >... the common practice of C programmers putting each function in its own
|> >separate file makes the mistake double easy to fall into.  ...
|> 
|> This is the second "common C programming practice" you have raised
|> in this thread that is in fact NOT a common practice among skilled
|> C programmers.  If your argument is that C requires a certain
|> degree of expertise to use WELL, then you're wasting our time,
|> since that has never been in question.

On the contrary.  Putting each C procedure into a separate file _is_
common practice.  It is promoted as "good" style by C gurus.  Skilled
C programmers recommend it - they don't avoid it or condemn it.  The
reason is two fold: 1) common implementations of C will load _all_
procedures that were in the same source file even if only _one_ was
called - so you pay a penalty in loading dead code if you don't 
break your code into separate files; 2) UNIX code maintenence tools
(like make) are designed to operate on the _file_ level - which makes
one procedure per file a natural maintenence decision.

I _don't_ say that dividing code into separate files is "good"
style.  The advantage that interprocedure analysis _can_ be
carried out _within_ a file is a strong incentive to combine
routines into the same file. Further, "static" globals (that is
"private" variables) are an important tool for modularizing
code and verifying correctness.  Against that is the overhead
of loading a whole "file" when you call only one procedure.
It is a trade-off only the end user can intelligently make.

If the loaders on UNIX machines were modified to load only those
procedures which were actually called, then I would not hesitate
to recommend combining procedures into common files whenever
possible.

J. Giles

jeenglis@alcor.usc.edu (Joe English) (04/24/91)

jlg@cochiti.lanl.gov (Jim Giles) writes:
>In article <15904@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) writes:
>|> This is the second "common C programming practice" you have raised
>|> in this thread that is in fact NOT a common practice among skilled
>|> C programmers.  If your argument is that C requires a certain
>|> degree of expertise to use WELL, then you're wasting our time,
>|> since that has never been in question.
>
>On the contrary.  Putting each C procedure into a separate file _is_
>common practice.  It is promoted as "good" style by C gurus.  Skilled
>C programmers recommend it - they don't avoid it or condemn it.  

I've never heard that style promoted by any C gurus.  I've never seen
that style *used* by any C gurus.  I don't write C programs that way,
no one I know writes C programs that way, and if you had ever read
any of the source code posted to the net by various comp.lang.c
luminaries you'd see that *they* don't write C programs that way either.  

(The vast majority of all the Fortran code I've seen, on the other
hand, *is* written that way, but that's OK since Fortran can be
optimized so much better than C that interprocedural optimizations
aren't necessary.)
 
>The
>reason is two fold: 1) common implementations of C will load _all_
>procedures that were in the same source file even if only _one_ was
>called - so you pay a penalty in loading dead code if you don't 
>break your code into separate files; 2) UNIX code maintenence tools
>(like make) are designed to operate on the _file_ level - which makes
>one procedure per file a natural maintenence decision.

That makes putting one *module* or *group of related functions*
in one file a natural maintenance decision.  A lot of C programs
*are* written this way.

Jim will probably ignore this posting.

--Joe English

  jeenglis@alcor.usc.edu

scs@adam.mit.edu (Steve Summit) (04/24/91)

In article <16815@chaph.usc.edu> jeenglis@alcor.usc.edu (Joe English) writes:
>jlg@cochiti.lanl.gov (Jim Giles) writes:
>>On the contrary.  Putting each C procedure into a separate file _is_
>>common practice.  It is promoted as "good" style by C gurus.  Skilled
>>C programmers recommend it - they don't avoid it or condemn it.  
>
>I've never heard that style promoted by any C gurus.  I've never seen
>that style *used* by any C gurus.  I don't write C programs that way,
>no one I know writes C programs that way...

Like (nearly) everything else, this issue is not cut-and-dried,
and arguments must be evaluated, on their merits, with respect to
the problem at hand.

When writing a large program, closely related functions can well
be placed in the same source file, both for logical cohesiveness
and to allow information hiding via file-scope static variables.

When writing a general-purpose library, however, it is a very
good idea to use a very fine, one-subroutine-or-nearly-so-per-
source-file granularity, since a given application being linked
against the library will usually use only a fraction of its
routines.  (To be sure, a "smarter" linker could help here, by
doing only partial loads of object files, but that's never
something I've thought a linker was "supposed" to do -- loading
only what's needed is exactly what libraries are for, at least in
the C/Unix "world" I'm used to.)  It's true that fine granularity
can work against enforced data hiding, but naming conventions (to
avoid name collisions, even if the "private" data isn't truly
hidden) work well in practice.

(If you are writing a general-purpose library which contains any
extensions in the form of newer routines which users might not
know about, putting each one in its own file is mandatory, so
that it cannot get pulled in when not needed and cause a name
clash.  For example, ANSI C does not prohibit implementors from
placing nonstandard routines in the C run-time library, as long
as their presence there cannot hurt oblivious programmers who
happen to have their own routines with the same names.)

In the (interminable) debate leading up to this side thread, I
suspect that Jim Giles has been thinking mainly or exclusively
about writing libraries (which furthermore will be used without
source available), so the difficulty of achieving good intermodule
optimization looms large for him.  For people who are thinking
instead about more standalone applications programs, or are not
focusing on one aspect of one problem at all, the issue is less
interesting and/or less exciting and/or more amenable to solution.

The one thing I was going to contribute to the "low level
optimization" thread was to suggest that people watch their
underlying assumptions, hidden agendas, and foregone conclusions --
if those don't match, you can argue forever.

                                            Steve Summit
                                            scs@adam.mit.edu

gwyn@smoke.brl.mil (Doug Gwyn) (04/24/91)

In article <22354@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
-On the contrary.  Putting each C procedure into a separate file _is_
-common practice.  It is promoted as "good" style by C gurus.  Skilled
-C programmers recommend it - they don't avoid it or condemn it.

Gee, thanks for telling me what C gurus recommend.

-If the loaders on UNIX machines were modified to load only those
-procedures which were actually called, then I would not hesitate
-to recommend combining procedures into common files whenever
-possible.

Oh, so THAT's what you mean by "C guru" and "skilled C programmer":
yourself.  I was wondering.

henry@zoo.toronto.edu (Henry Spencer) (04/24/91)

In article <22354@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
>On the contrary.  Putting each C procedure into a separate file _is_
>common practice.  It is promoted as "good" style by C gurus...

Jim, you've gone round the bend.  Either cite references for this or shut up.
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  henry@zoo.toronto.edu  utzoo!henry

oz@yunexus.yorku.ca (Ozan Yigit) (04/25/91)

In article <22354@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:

>On the contrary.  Putting each C procedure into a separate file _is_
>common practice.  It is promoted as "good" style by C gurus. ...

Jim, you have no idea what you are talking about, so why talk so
much? Remember that a closed mouth gathers no foot. 

oz

jedelen@slate.mines.colorado.edu (Jeff Edelen) (04/25/91)

In article <1991Apr24.155719.10182@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>In article <22354@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
>>On the contrary.  Putting each C procedure into a separate file _is_
>>common practice.  It is promoted as "good" style by C gurus...
>
>Jim, you've gone round the bend.  Either cite references for this or shut up.

Based on the complete text of Jim's article, I doubt he meant what I'm about
to propose, but...

If you regard a "procedure" as a _collection_ of functions to perform a
given task, his statement makes sense.  Of course, this observation can
at best give rise to bickering about terminology, but we see so very
little of that around here as it is :-)

-jeff

pefv700@perv.pe.utexas.edu (04/25/91)

In article <22524@yunexus.YorkU.CA>, oz@yunexus.yorku.ca (Ozan Yigit) writes...
>In article <22354@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
> 
>>On the contrary.  Putting each C procedure into a separate file _is_
>>common practice.  It is promoted as "good" style by C gurus. ...

I have also read or heard this, but don't remember where.  I think I 
remember jlg stating that it was common in FORTRAN to do this (although I
may be wrong).  To be honest, I had never even heard of splitting source
code for an executable into multiple files and certainly didn't know that
it was allowed in FORTRAN.

> 
>Jim, you have no idea what you are talking about, so why talk so
>much? Remember that a closed mouth gathers no foot. 
> 
>oz

Wow, where does everyone get off telling him to shut up.  If you don't
respond, he'll quit posting.

jlg@cochiti.lanl.gov (Jim Giles) (04/26/91)

In article <16815@chaph.usc.edu>, jeenglis@alcor.usc.edu (Joe English) writes:
|> jlg@cochiti.lanl.gov (Jim Giles) writes:
|> >[...]
|> >On the contrary.  Putting each C procedure into a separate file _is_
|> >common practice.  It is promoted as "good" style by C gurus.  Skilled
|> >C programmers recommend it - they don't avoid it or condemn it. 
|> [...]
|> (The vast majority of all the Fortran code I've seen, on the other
|> hand, *is* written that way, but that's OK since Fortran can be
|> optimized so much better than C that interprocedural optimizations
|> aren't necessary.)

I've never seen Fortran fragmented into one file per routine except
for those very few Fortran programs written by ex-C programmers.
Many half-million line Fortran programs I've seen were maintained
in just a single file - all thousand-odd subroutines.  I don't agree
maintaining code quite so monolithically, but it is _cartainly_ not
fragmented as you are claiming.

In C, on the other hand, fragmenting seems to be to order of the day.
For example, all the UNIX utilities on Cray UNICOS are maintained
as huge numbers of separate source files.  The X11R4 version of
xterm is distributed as 16 separate source files (even though it's
a fairly small program that does most of its work by calling widgets).
Speaking of which, the widgets are distributed as over a hundred
little .c files - mostly one per procedure.

One file per procedure appears to be standard C practice to me.

|> [...]
|> Jim will probably ignore this posting.

Dream on.

J. Giles

jlg@cochiti.lanl.gov (Jim Giles) (04/26/91)

In article <1991Apr24.050556.16405@athena.mit.edu>, scs@adam.mit.edu (Steve Summit) writes:
|> [... bunch of stuff about trade-offs of separate files for each 
|>      procedure - most of which I agree with ...]
|>
|> The one thing I was going to contribute to the "low level
|> optimization" thread was to suggest that people watch their
|> underlying assumptions, hidden agendas, and foregone conclusions --
|> if those don't match, you can argue forever.

One of the assumptions (which is still valid most places) is that
no interprocedural analysis is done - even _within_ a file, even 
though the language permits such optimizations.  The result is that
there really is a tendency to maintain C code as numerous separate
files.  Even closely related codes tend to be fragmented this way.
For example: the X11R4 xterm program is maintained as 16 separate
source files even though it is _one_ utility and I know of no other
program which shares any code with these 16 files.  There is not
really any reason for this code to be maintained in more than _one_
file.

I don't maintain that keeping code in separate file is necessarily
bad or good.  But to pretend that it is not common practice is to 
ignore reality.  This common practice may in (the near) future result 
in less efficient code because of missed optimization.

J. Giles

shirley@gothamcity.jsc.nasa.gov (Bill Shirley) (04/26/91)

In article <22524@yunexus.YorkU.CA>, oz@yunexus.yorku.ca (Ozan Yigit) writes:
|> In article <22354@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
|> 
|> >On the contrary.  Putting each C procedure into a separate file _is_
|> >common practice.  It is promoted as "good" style by C gurus. ...
|> 
|> Jim, you have no idea what you are talking about, so why talk so
|> much? Remember that a closed mouth gathers no foot. 
|> 
|> oz


Isn't the first comment basically aimed at developing procudures to be put
into a library.  Thus, if each procedure is in a different file then it also
has a different object file and when linked in from a library only those
procedures that are used need to be included in the executable.

	Bill S.

tmb@ai.mit.edu (Thomas M. Breuel) (04/27/91)

In article <22354@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
   On the contrary.  Putting each C procedure into a separate file _is_
   common practice.  It is promoted as "good" style by C gurus.  Skilled
   C programmers recommend it - they don't avoid it or condemn it.

Lest some novice C programmer get confused out there, jlg's statement
is false. For example, for X11R4 dix server code, xterm, and twm, the
average is about 20-30 functions per source file, and that is probably
pretty typical of C code in general.

Common C practice is to put related functions into a single source
file, since C implements a simple form of modularization at source
file (read, compilation unit) level, via the "static" declaration.

Back in the days of the PDP-11 with its 64k code space, people would
split up source code to libraries such that each source file had only
one function in it. This was because the UNIX link editor pulls in all
functions and global data defined inside the same file from a library
even if they are not all used.

There was some thought given to modifying the UNIX link editor, but
with the advent of virtual memory and shared libraries, there is very
little incentive to do so on UNIX systems. Some vendors actually have
more sophisticated link editors that manage to pull apart object
files, for example for cross-compilers for embedded controllers, where
every byte counts.

I know of no C programmer who considered this sort of butchery
(splitting up your sources to get around a limitation of the link
editor) "good style", though.

In terms of compilation speed and code optimization, having only one
function per source file is about the worst you can possibly do: you
pay the cost for parsing lots of include files for each function you
compile, and, with most compilers, you inhibit all global
optimization.

						Thomas.

boyd@cs.unca.edu (Mark Boyd) (04/27/91)

FORTRAN scoping rules are different from C. It doesn't matter whether
you put all the suprograms in one file or put them all in separate
files, except that it will compile faster if you put them all together!

With C you can use files containing groups of functions to control the
scope of variables. With FORTRAN you can't. At least not on any
'FORTRAN' that I've used 8^). So what does this have to do with C?

	Mark Boyd

grogers@convex.com (Geoffrey Rogers) (04/27/91)

In article <TMB.91Apr26145719@volterra.ai.mit.edu> tmb@ai.mit.edu (Thomas M. Breuel) writes:
>In terms of compilation speed and code optimization, having only one
>function per source file is about the worst you can possibly do: you
>pay the cost for parsing lots of include files for each function you
>compile, and, with most compilers, you inhibit all global optimization.
	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^	
Huh???? What do you mean by global optimization? Most texts on optimization
consider global optimization to be between basic blocks within a procdure.
Having one function per source file does not inhibit this. Everything
else that you said is true/good common sense.

+------------------------------------+---------------------------------+
| Geoffrey C. Rogers   		     | "Whose brain did you get?"      |
| grogers@convex.com                 | "Abbie Normal!"                 |
| {sun,uunet,uiucdcs}!convex!grogers |                                 |
+------------------------------------+---------------------------------+

bhoughto@pima.intel.com (Blair P. Houghton) (04/28/91)

In article <1991Apr27.014136.25697@rock.concert.net> boyd@cs.unca.edu (Mark Boyd) writes:
>FORTRAN scoping rules are different from C. It doesn't matter whether
>you put all the suprograms in one file or put them all in separate
>files, except that it will compile faster if you put them all together!

Tetural issue:  C can operate in the same way, by use of
the `extern' keyword.

				--Blair
				  "Up scope!"

gaynor@yoko.rutgers.edu (Silver) (04/28/91)

> Putting each C procedure into a separate file _is_ common practice.  It is
> promoted as "good" style by C gurus.  Skilled C programmers recommend it -
> they don't avoid it or condemn it.

Can't stand this practice myself and I'd consider myself a skilled C
programmer.  Makes editing and searching the source too damned cumbersome.
Instead, I recommend that you use a logical grouping (I usually do this on the
data type and main levels), whatever seems logical to you, and only further
break the source down into seperate files for compilation speedups.  And
annotate such deviations from your grouping conventions in the `currupted'
file.

My $/50, [Ag] gaynor@paul.rutgers.edu

mike@bria.UUCP (Michael Stefanik) (04/28/91)

In an article, jlg@cochiti.lanl.gov (Jim Giles) writes:
>On the contrary.  Putting each C procedure into a separate file _is_
>common practice.  It is promoted as "good" style by C gurus.  Skilled
>C programmers recommend it - they don't avoid it or condemn it. 

Okay, I'll throw in my two pence.  As a general rule, splitting up
source into a gaggle of files is nauseating -- however, I have found
it to be useful when building a library.  Considering that I am using
a poor 'ol RT with it's brain-damaged C compiler, it is not in my
best interest to have it wade (slowly) through a large source file.
At best, it just takes a long time; at worst, it will choke and die.

Besides, this is all rather aesthetic; if a ton o' files that suck up half
the inodes on your machine give you a cheap thrill, why deny yourself?

Gotta love those Makefiles!

-- 
Michael Stefanik, MGI Inc, Los Angeles | Opinions stated are never realistic
Title of the week: Systems Engineer    | UUCP: ...!uunet!bria!mike
-------------------------------------------------------------------------------
If MS-DOS didn't exist, who would UNIX programmers have to make fun of?

gwyn@smoke.brl.mil (Doug Gwyn) (04/29/91)

In article <22636@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
>For example, all the UNIX utilities on Cray UNICOS are maintained
>as huge numbers of separate source files.

This sounded completely wrong, so I checked on our X/MP UNICOS system
and found that it is set up the same as other UNIX implementations,
namely /usr/src/cmd contains a SINGLE source file per utility or else
a directory for a utility that consists of several source files.  Most
utilities have all their code in a single file, and none of the ones
that have several source files use one file per function.

tmb@ai.mit.edu (Thomas M. Breuel) (04/29/91)

In article <1991Apr27.024634.586@convex.com> grogers@convex.com (Geoffrey Rogers) writes:
   In article <TMB.91Apr26145719@volterra.ai.mit.edu> tmb@ai.mit.edu (Thomas M. Breuel) writes:
   >In terms of compilation speed and code optimization, having only one
   >function per source file is about the worst you can possibly do: you
   >pay the cost for parsing lots of include files for each function you
   >compile, and, with most compilers, you inhibit all global optimization.
		  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^	
   Huh???? What do you mean by global optimization? Most texts on optimization
   consider global optimization to be between basic blocks within a procdure.
   Having one function per source file does not inhibit this. Everything
   else that you said is true/good common sense.

If you don't like the term "global" (which is often used in this
sense), call it "interprocedural". For example, GNU C performs
inlining at compile time, not link time, and this is inhibited by
putting each function into a separate file. Likewise, a compiler
can only determine that a function is side-effect free if the
source code to that function is available at compile time.

richard@aiai.ed.ac.uk (Richard Tobin) (04/29/91)

In article <22636@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
>as huge numbers of separate source files.  The X11R4 version of
>xterm is distributed as 16 separate source files (even though it's
>a fairly small program that does most of its work by calling widgets).

13 of these contain code.  They contain an average of 17.3 procedures
each.

>Speaking of which, the widgets are distributed as over a hundred
>little .c files - mostly one per procedure.

One (or a very small number) of procedures per file is common for files
which are to be combined into a library, for obvious reasons.

>One file per procedure appears to be standard C practice to me.

10,000 line procedures, spaghetti gotos, and complete lack of
structure appear to be standard Fortran practice to me, but then
perhaps I know as much about that as you do about C practice.

-- Richard
-- 
Richard Tobin,                       JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,           ARPA:  R.Tobin%uk.ac.ed@nsfnet-relay.ac.uk
Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/29/91)

In article <TMB.91Apr29014917@volterra.ai.mit.edu> tmb@ai.mit.edu (Thomas M. Breuel) writes:
> Likewise, a compiler
> can only determine that a function is side-effect free if the
> source code to that function is available at compile time.

Yeah. What Jim's really trying to say (but doing a nauseatingly bad job
of saying) is that such information should be part of the procedure-call
interface. If you declare a function ``pure'' (some compilers allow
this), then the function is not allowed to use global variables or call
impure functions, but any caller can assume that the function will
return the same value for the same inputs. Similarly, if you declare a
function with ``arguments 1 and 2 aren't aliased'', then any caller must
make sure that this is true, but the optimizer will have an easier time
on vector machines.

The interesting issues here are what sort of assertions to allow, how
much the compiler should check, etc. A number of experimental languages
have addressed these issues, more or less successfully.

I think Jim's ignorance of the C standard, C common practice, and
available C compilers has been quite thoroughly demonstrated in this
thread, and I hope my comments here make clear that Jim really isn't
thinking about C at all. So can we stop discussing this in comp.lang.c?

---Dan

jlg@cochiti.lanl.gov (Jim Giles) (04/29/91)

In article <1991Apr27.024634.586@convex.com>, grogers@convex.com (Geoffrey Rogers) writes:
|> In article <TMB.91Apr26145719@volterra.ai.mit.edu> tmb@ai.mit.edu (Thomas M. Breuel) writes:
|> >compile, and, with most compilers, you inhibit all global optimization.
|> 	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^	
|> Huh???? What do you mean by global optimization? Most texts on optimization
|> consider global optimization to be between basic blocks within a procdure.
|> Having one function per source file does not inhibit this. Everything
|> else that you said is true/good common sense.

As uncharacteristic as it is for me to defend people that I disagree
with, it is legitimate to refer to the use of IM analysis to improve
optimization of global data and procedure arguments as 'global 
optimization'.  Is is also true that in the field of compiler 
construction, the term is use exclusively to mean optimization
of all code _within_ a given compilation unit but _across_ basic
block boundaries.  The language is (unfortunately) used both ways
in the programming community as a whole.  Nothing you can do about
it but grin and bear it.

J. Giles

jockc@hammer.idsila.com (PRIV Account) (04/30/91)

In article <22649@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
>I don't maintain that keeping code in separate file is necessarily
>bad or good.  But to pretend that it is not common practice is to 
>ignore reality.  This common practice may in (the near) future result 
>in less efficient code because of missed optimization.

My 2 cents.  I have never separated code to this degree (1 function
per file), nor have I ever known anyone who did it, nor have I ever seen
any packages from the net (or anywhere else) that do it.  

I breakdown source into files containing related functions, ie,
routines for painting screens in a file, file io stuff in a file,
ipc junk in a file, etc.

jockc@hammer.idsila.com

daw@cbnewsh.att.com (David Wolverton) (04/30/91)

In article <22649@lanl.gov>, jlg@cochiti.lanl.gov (Jim Giles) writes:
> One of the assumptions (which is still valid most places) is that
> no interprocedural analysis is done - even _within_ a file, even 
> though the language permits such optimizations.  The result is that
> there really is a tendency to maintain C code as numerous separate
> files.  ...[stuff deleted]...
> I don't maintain that keeping code in separate file is necessarily
> bad or good.  But to pretend that it is not common practice is to 
> ignore reality.  This common practice may in (the near) future result 
> in less efficient code because of missed optimization.

I can't say about "most places", but I _can_ say that we
built a commercially-available 3B2 C compiler here in 1986
that did some interprocedural stuff within a source file.

Our biggest customer was a project with _thousands_ of
functions, one per file.  We tried mightily to get them
to group related functions into a single file, but their
"project methodology" wouldn't allow it.  So they could
never take advantage of that group of optimizations.

Dave Wolverton
AT&T Bell Labs

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (04/30/91)

In article <22649@lanl.gov>, jlg@cochiti.lanl.gov (Jim Giles) writes:
> Even closely related codes tend to be fragmented this way.
> For example: the X11R4 xterm program is maintained as 16 separate
> source files even though it is _one_ utility and I know of no other
> program which shares any code with these 16 files.  There is not
> really any reason for this code to be maintained in more than _one_
> file.

There are two separate good reasons that I can think of.
Not having read any of the X sources, I have no idea which if either
is relevent to xterm.

1.  Modules.  Functions and variables declared 'static' are private to
    a file, and can't be confused with functions or variables of the
    same name in other files.  This is a Good Thing.

    It would, of course, be a Better Thing to have an explicit module
    construct in the language.  See Modula-2, Modula-3, Ada, Fortran-90.
    comp.std.c++ were talking about a module construct for C++.
    
2.  Recompilation speed.  If you change one file, you recompile one file.
    That can be a lot faster than recompiling the whole program.

    It would, of course, be a Better Thing to have compilers which just
    recompiled the parts of the program which depended on the change.
    In the 70s I had the privilege of using a Burroughs B6700; now that
    was a batch, card-oriented, system, but if you gave their compilers
    a "patch file" they were smart enough to recompile just the routines
    which had been affected by the changes.  It worked wonderfully well;
    the operating system was *one* giant Algol (well, Espol) source file,
    and a patch could be compiled in a minute.  One thing that helped was
    that macros (DEFINE) in their languages were lexically scoped.  All
    this on a machine which was small and slow by comparison with today's
    UNIX boxes.

I like C, but if I had a PC, I'd buy an Ada compiler for it.

> I don't maintain that keeping code in separate file is necessarily
> bad or good.  But to pretend that it is not common practice is to 
> ignore reality.  This common practice may in (the near) future result 
> in less efficient code because of missed optimization.

It is difficult to see why.  Is there any reason why a C compiler should
not have an option "-c.a" (make a ".a" file) so that
	cc -o lib.a -c.a *.c
would make a library file in one step, with cross-file optimisation
possible?  The IBM mainframes and VAX/VMS support "concatenated files",
where 
	compile foo.c+bar.c+ugh.c
acts _as_though_ the files had been concatenated; if you just imagine
a directive "remove static symbols from symbol table" interposed between
the files, compiling a collection of files into one object with cross-
file optimisation ought to be easy.
-- 
Bad things happen periodically, and they're going to happen to somebody.
Why not you?					-- John Allen Paulos.

meissner@osf.org (Michael Meissner) (04/30/91)

In article <1991Apr29.220139.28983@cbnewsh.att.com> daw@cbnewsh.att.com (David Wolverton) writes:

| In article <22649@lanl.gov>, jlg@cochiti.lanl.gov (Jim Giles) writes:
| > One of the assumptions (which is still valid most places) is that
| > no interprocedural analysis is done - even _within_ a file, even 
| > though the language permits such optimizations.  The result is that
| > there really is a tendency to maintain C code as numerous separate
| > files.  ...[stuff deleted]...
| > I don't maintain that keeping code in separate file is necessarily
| > bad or good.  But to pretend that it is not common practice is to 
| > ignore reality.  This common practice may in (the near) future result 
| > in less efficient code because of missed optimization.
| 
| I can't say about "most places", but I _can_ say that we
| built a commercially-available 3B2 C compiler here in 1986
| that did some interprocedural stuff within a source file.
| 
| Our biggest customer was a project with _thousands_ of
| functions, one per file.  We tried mightily to get them
| to group related functions into a single file, but their
| "project methodology" wouldn't allow it.  So they could
| never take advantage of that group of optimizations.

One way to 'solve' this problem is to have one file #include each of
the different .c files.  That way for debugging, you get fast
turnaround time (only recompile each file that changed in the typical
fashion), and for production you get interprocedural optimizations.
Note typically for compiling everything together, you typically need
lots of physical memory to run the compiler.
--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

Considering the flames and intolerance, shouldn't USENET be spelled ABUSENET?

tmb@ai.mit.edu (Thomas M. Breuel) (05/12/91)

In article <240@sojurn.UUCP> mike@sojurn.UUCP (Mike Sangrey) quotes:

   In article <TMB.91Apr26145719@volterra.ai.mit.edu> tmb@ai.mit.edu (Thomas M. Breuel) writes:
   >In article <22354@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
   >   On the contrary.  Putting each C procedure into a separate file _is_
   >   common practice.  It is promoted as "good" style by C gurus.  Skilled
   >   C programmers recommend it - they don't avoid it or condemn it.

   I dare say that just because it's a function doesn't mean it should be
   in a separate file.

Please be more careful when you quote. The text you quoted had
nothing do to with me, yet in your posting, it has my name associated
with it...