[net.lang.c] A Modest Extension to the C Preprocessor

jbn@wdl1.UUCP (John B. Nagle) (08/01/84)

I propose that a new preprocessor directive be defined as follows:

	#use FILENAME

to be interpreted identically to ``#include'', except that if FILENAME
has already been included (either via #include or #use) during this
compilation, #use does nothing.


The intent here is to resolve the problem of dependency in header files.
If all header files (``*.h'') by convention contain #use statements for all 
the header files they need, then C program text files (``*.c'') need only
include the files the C program itself needs, and need not worry about
internal dependencies in header file libraries.  So this does for header
files what linkers do for object files.

It might seem tempting to change the semantics of #include to work this way,
but this would introduce an incompatibility; some programs may be using
#include to include things of which they want multiple copies.

Portability would be increased by this enhancement, since at present the
dependency structure of header files is not standardized, even between
versions of UNIX (anyone doubting this should port something from V7 to 
system 5), and with this enhancement, the internal structure of the header 
files disappears from the user's programs.

Comments?

					John Nagle
					Ford Aerospace and Communications Corp.

elvy@harvard.ARPA (Marc Elvy) (08/03/84)

Actually, the #use suggestion sounds like a practical idea, but I doubt the
C "purists" will go for it.  Taking the suggestion one step farther, one
might use something like

	# require	DEFINITION	file

In case it is not obvious, this would act as follows:  If DEFINITION is
already defined, then the statement could be ignored; if DEFINITION is
not defined, then "file" would be #included.  This would, I suppose, take
the place of all the

	# ifndef	DEFINITION
	# include	file
	# endif		DEFINITION

sequences which are probably around.  Something like this would certainly
make my life a lot happier, since I am constantly having fights about
whether .h files should depend upon other .h files already being #included.
Incidentally, this is not my idea, per se -- the (require) function exists
in at least one Lisp system (T) and probably several others.

Marc

		      Marc A. Elvy  ( elvy@harvard.{arpa,uucp} )
			     Aiken Computation Laboratory
				  Harvard University

brownell@harvard.ARPA (Dave Brownell) (08/03/84)

>=<

Better and simpler is to make the #include files safe for multiple
inclusions.  It's so simple I'm amazed that neither Berkeley nor
Bell have done it:

    #ifndef	FOO_H_INCLUDED
    #define	FOO_H_INCLUDED

	/* contents of "foo.h" */

    #endif	FOO_H_INCLUDED

This is compatible with any standard CPP.





Dave Brownell
Sequoia Systems Inc.
{allegra,floyd,ihnp4,seismo}!harvard!sequoia!brownell

joemu@tekecs.UUCP (Joe Mueller) (08/03/84)

This feature has already been discussed in this group. The problem
with it is how to determine if the file has been included before.
For example, are foo.h and ../bar/foo.h the same?
Is bar.h which is a link to foo.h is the same as foo.h?

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (08/04/84)

#ifndef	FOO_H_INCLUDED
#define	FOO_H_INCLUDED

	/* contents of "foo.h" */

#endif	FOO_H_INCLUDED

is an excellent solution to the "problem", if it be one, that
does not penalize those that had no problem with this business
in the first place.  This also solves the problem of making sure
that prerequisite files such as <sys/types.h> are included:

#ifndef	SYSTYPES_H_INCLUDED
#include	<sys/types.h>
#endif

	/* stuff that uses <sys/types.h> typedefs */

Good work, Dave!  I would, however, suggest shortening the
tag symbols a bit; probably "_H" could be safely removed.

jack@vu44.UUCP (Jack Jansen) (08/07/84)

I think that a more elegant way of getting the functionality of
the proposed #use statement is an 'included' preprocessor function.
Like in

#if !included("def.h")
#include "def.h"
#endif

I wouldn't know what the syntax should be for <stdio.h>, though.
It could be included(<stdio.h>), or included("stdio.h"); but the
first one looks quite non-C to me, and the second one is clearly
ambigous.

	Jack Jansen, {philabs|decvax}!mcvax!vu44!jack

dmmartindale@watcgl.UUCP (Dave Martindale) (08/07/84)

Telling whether "foo.h" and "../bar/foo.h" are the same file is easy under
UNIX (via the device/inumber pair returned from stat) but might be difficult
under other operating systems.