[comp.lang.c++] #pragma once

rfg@ics.uci.edu (Ron Guilmette) (10/28/89)

In article <2082@plx.UUCP> johnc@plx.UUCP (John C.) writes:
>
>b) Regarding modifications to the semantics of #include (so the compiler
>would keep track of which file names had already been scanned), you
>might be interested to know that MetaWare's compilers have had a
>"conditional include" (C_Include) directive for several years now,
>which does exactly this.  Perhaps the preferred language change, if 
>any, is to define such a "conditional-include" directive, perhaps 
>"#cond_include" or "#c_include".  [How about it, Dr. Stroustrup?]

Think about what you are saying.

If a given include file should (or must) only be included once, then
that fact is a property of the include file itself, and not a property
of any file which may include it.

That is why the GNU C and C++ compilers have implemented the #pragma once
construct, which can be placed in a given include file to signify (to the
compiler) that the given file should only be included once (during a
given compilation) regardless of the number of include "requests" for
the given file.

By the way, I have been sitting here reading numerous items about this
stale old problem (multiple inclusions) and I have noticed that every
scheme that has been proposed here recently has one or more of the following
major deficiencies:

	*  It is no more efficient than normal multiple inclusion
	   (given ANSI C's rules regarding the tokenization of
	    material inside of #if-#endif pairs).

        *  It directly violates ANSI C semantics.

	*  It is not implemented (i.e. just a pipe-dream).

Mind you, the #pragma once construct probably has deficiency #2, but I think
that it tiptoes around the rules rather than trying to overtly overthrow them.

// rfg

John_-_Nagle@cup.portal.com (10/29/89)

     While there appears to be an ANSI requirement that source text bypassed
due to preprocessor commands be tokenized and error messages generated
when appropriate, there's no reason for this to happen more than once per
include file.  So objections based on that rule are spurious.

     The "#pragma once" approach is a good idea.  But a pragma represents
an explicitly nonstandard approach.  This should be standardized.

     Common LISP has "require", which has the right semantics for this
situation.  Perhaps we could use that keyword.

     It's worth considering that this new feature be added to C++ only,
not C, which is more firmly standardized.  In C++, dependencies tend to
be more complex than in C, and a larger percentage of the content of the
program tends to reside in include files in C++, since most class definitions
are in include files.  

     So how about

	#require FILENAME

as the one-time inclusion mechanism for C++. 

     The ultimate goal is that all include files contain "require" statements
for everything they need, so that order of inclusion in the ".c" files isn't
an issue and the user of a library doesn't have to worry about including
too little or too much.

     Worth noting is that the basic concept of "make" doesn't really handle
well the use of include in include files.  Something needs to be done about
this.

					John Nagle

david@cs.washington.edu (David Callahan) (10/30/89)

In article <23464@cup.portal.com> John_-_Nagle@cup.portal.com writes:
>
>     Common LISP has "require", which has the right semantics for this
>situation.  Perhaps we could use that keyword.
>
...
>     So how about
>
>	#require FILENAME
>
>as the one-time inclusion mechanism for C++. 
>
>     The ultimate goal is that all include files contain "require" statements
>for everything they need, so that order of inclusion in the ".c" files isn't
>an issue and the user of a library doesn't have to worry about including
>too little or too much.

I think you'd want some insulation from the vagaries of file systems.
How about:

	#pragma require function "file"

where "file" defaults to function if it is not provided.
And in "file":

	#pragma provide function

Another advantage of this mechanism is that header files could be
collected into a library and some tool similar to "ranlib" used to
cross-refedrence function to filename. Then of course, its one small
step to treating every "class foo { ... }" as implying "provide foo".

-- 
David Callahan  (david@tera.com, david@june.cs.washington.edu,david@rice.edu)
Tera Computer Co. 	400 North 34th Street  		Seattle WA, 98103

jnh@ecemwl.ncsu.edu (Joseph N. Hall) (10/30/89)

In article <23464@cup.portal.com> John_-_Nagle@cup.portal.com writes:
>     It's worth considering that this new feature be added to C++ only,
>not C, which is more firmly standardized.  In C++, dependencies tend to
>be more complex than in C, and a larger percentage of the content of the
>program tends to reside in include files in C++, since most class definitions
>are in include files.  
> [how about...]
>	#require FILENAME
>
>as the one-time inclusion mechanism for C++. 

I definitely support the use of a "#require" mechanism.  Personally, I'd
like to see some sort of explicit support for a precompiled "interface
library" from which necessary declarations, macros, etc., can be extracted
quickly and efficiently.  I find it infuriating that one is penalized for
keeping source files to a reasonable length (say, 1000 lines) when headers
grow to lengths of 2000-10,000 lines and take several times longer to
compile than the actual definitions in the source file ...


v   v sssss|| joseph hall                      || 4116 Brewster Drive
 v v s   s || jnh@ecemwl.ncsu.edu (Internet)   || Raleigh, NC  27606
  v   sss  || SP Software/CAD Tool Developer, Mac Hacker and Keyboardist
-----------|| Disclaimer: NCSU may not share my views, but is welcome to.

henry@utzoo.uucp (Henry Spencer) (10/31/89)

In article <23464@cup.portal.com> John_-_Nagle@cup.portal.com writes:
>     The "#pragma once" approach is a good idea.  But a pragma represents
>an explicitly nonstandard approach.  This should be standardized.
>
>     Common LISP has "require", which has the right semantics for this
>situation.  Perhaps we could use that keyword.

Better yet, why not mandate intelligent preprocessors, which recognize
include files that start with "#ifndef FOO_H" and end with "#endif"?
If we are going to mandate a change, why not mandate one that introduces
no new keywords and no incompatibility?
-- 
A bit of tolerance is worth a  |     Henry Spencer at U of Toronto Zoology
megabyte of flaming.           | uunet!attcan!utzoo!henry henry@zoo.toronto.edu