[net.lang.c] ANSI C: CPP predefined constants vs. <whoami.h>

keld@diku.UUCP (Keld J|rn Simonsen) (10/19/84)

<>

One thing I would like from the C standard, is that
as much software as possible could compile *unmodified* on different 
processor types, under different families of operating 
systems, and under different levels of an operating system.
This should be done by #ifdef-ing or testing on some well
defined constants, which should be agreed upon (obviously!).

Lately there has been some discussion on C preprocessor defined
constants. Well this is good for thing as __LINE__ numbers and
__DATE__ compiled, but for operating systems levels, processor type, 
machine brand etc. I think it is a very bad idea.
I advocated a while ago on the net for use of the <whoami.h> include 
file as a solution to some problems. I will elaborate a little more 
on this seen from an ANSI C standard point of view.

I think it is a bad idea to have this information build in the C
compiler. C is not the only systems language around in the Unix
world, we also have Pascal and Modula-2. The ANSI C is not intended
for use with the Unix system only, there are C compilers for
CP/M, MS-DOS, OS/370, VMS etc, and all these systems surely have
other systems programming languages interested in knowing
OS level, processor type etc. This information should be 
stored in a *unique* place retrievable from all languages/
software interested, and all important site dependent information
should also be collected here, so you only have one place to go
when the ordinary system adminstrator installs his/her *binary*
system. 

I think the way to configure in this one unique place should provide
both for binary only and source systems. This boils down to 
#ifdef vs. getfoobar(3) techniques, and I think there is a place for 
obtaining information in both ways for the same item. E.g. nowadays
we compile conditionally on the OS level V7/BSD/S5. Someday we may
have a common object format and file system format constant over 
several levels of the OS, so the same application program could
run with only minor actions to OS level differencies under these OSes.
We also may have machines running several different flavors of an OS
(e.g. 4.2BSD and System V) at the same time with only minor differences.
A source system would be happy with some C preprocessor syntax like 
#define statements, and that could go for several other systems 
programming languages. The binary system would go for some termcap(5)
like information base, it could perfectly be in *C header* syntax.
We then just have to write info routines, e.g. defines(3) -
get string value - and definen(3) - get num value - 
netnews is already distributed with such routines, and they are simple!
We then would have one *unique* place to configure and seek for system
dependent information for both source and binary systems.

Using <whoami.h>  is simple (Unix style, folks!). Every system
manager can edit this include file; it is not so easy to 
get information out of a binary file (like the kernel), or even change 
or add items in it. <whoami.h> can exist easily on even V6, PWB and S5,
and can easily be updated to include items like organization
name needed for netnews, but not provided by any existing 
Unix OS in system calls. So we could eliminate ifdef-ed calls to
gethostname(2), uname(2) and what they call it on IBM, Sperry (MSCON$)
etc. I.e. simpler programs! Adding a <whoami.h> file on an existing 
system is simple, so *existing* C compilers could easily be made to 
comform to the standard on this point, also on UNIX systems already 
in service.

The problem of predefined constants unknown to a programmer is
also quite simple to solve, you just don't #include <whoami.h>!
So don't do it in CPP, use <whoami.h> instead!

Keld Simonsen, DIKU, U of Copenhagen         ...decvax!mcvax!diku!keld

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (10/20/84)

I don't see how conditional tests for different run-time environments
is going to solve the problem, since there will always be some
unanticipated environments and in any case few programmers are going
to prearrange code to accommodate all known systems; that's a lot of
extra work!

The cleanest approach seems to me to establish a common environment
for portable programs.  The /usr/group C environment standard was
supposed to be one such common environment.  Unfortunately they added
things like the locking call that can't be reasonably provided on all
systems and omitted things like tty ioctls that are needed by many
applications.

The policy in my Division is to target applications for a UNIX System
V environment (minus unique features like real-time IPC) unless it can
be demonstrated that a specific application depends on "native OS"
features in a way that cannot be accessed in the (emulated) UNIX
System V environment.  On foreign systems, someone has to implement
the common environment just once, then the applications come up with
practically no trouble.  This is much easier for the application
developer than trying to accommodate a variety of different
environments directly in his code.

So far I have implementations for:
	UNIX System V (trivial, just directory access routines)
	VAX 4.2BSD
	Gould UTX-32 (preliminary version)
	JHU/BRL PDP-11 UNIX
and am working on one for the Apple ][ (Aztec C under ProDOS).

stew@harvard.ARPA (Stew Rubenstein) (10/21/84)

Re Keld Simonsen's long message advocating the use of whoami.h:

I have much more experience with C on vms than on unix, but I can't
count the number of times I cursed the people who forced me to recompile
their software because the system name or some pathname was compiled
into the program.

In a perfect world, we would all have sources for all the programs we
ran, and compilers for all the languages in which they are written.
Unfortunately, this is not always the case!  Even when it is, it is a
pain to have to recompile the program (sometimes discovering a missing
include file or other piece) when installing it.

On VMS, there is a wonderful facility for dealing with this:  the
logical name.  For you unix folks, I guess this would be called a
systemwide environment variable.  You just do:

	$ DEFINE/SYSTEM SITE_NAME "MYNAME"
	$ DEFINE/SYSTEM PKG_LIBRARY DISK:[DIR]

and move the executable to the public program library.

Before I don my asbestos suit, I should point out that this is one of
the features that I consider to be good about VMS -- but I'm not so
closeminded that I refuse to admit it has \something/ worth copying...

And yes, I know this probably doesn't belong in net.lang.c, but having
just spent time trying to recompile some things just because they had a
compiled-in site name, I was feeling sensitive about the whoami.h topic.
And, for the record, I don't see why it is inappropriate to have
predefined symbols to deal with different operating systems.  Nor do I
see how moving them to whoami.h solves the problem.  Realistically,
portable software will have to know about the symbols defined on each
system for which it is ported.

And finally (for those who have waded through the above), a constructive
suggestion.  I can see how you might be worried about some future
preprocessor usurping your symbols.  The way to deal with this is to
adopt a convention for feature- and system-dependent symbols.  For
example, adopt the convention that symbols starting with sys_ or cpu_ be
reserved for the compiler.  Then SUN Microsystems can define sys_sun and
cpu_m68000, and VAX/VMS can define sys_vms and cpu_vax, and as long as
you avoid symbols of this type, you will be safe.

This need not cause every program in the world to break -- just adopt
this as a suggestion for future compiler implementors, and add them to
existing compilers when convenient.  As future compilers and cpus take
over, the convention will be more widely observed.
-- 
-----------------------
Stew Rubenstein     UUCP: ihnp4!harvard!stew
Harvard Chemistry   ARPA: stew@harvard