rfg@riunite.ACA.MCC.COM (Ron Guilmette) (03/20/89)
As someone pointed out recently, the subject of multiple
inclusion of individual include files was beaten to death
here not long ago.
At the risk of starting it all up again, I would like to
announce the availability of patches for the the GNU C
preprocessor (version 1.34) which implement the new #once
directive. These patches may be aquired by simply sending
me mail and requesting the patches. I hope that these patches
will soon become a standard part of the GNU releases, but till
then, I will distribute them.
The patch-kit also contains patches which implement two other
preprocessor extensions (both especially useful for C++). These
are described below.
The semantics of the #once directive are simple. The #once
directive causes any file it appears in to be included no more
than one time during any given individual compilation. This
directive only takes effect when it is seen. Thus, if "B.h"
includes "A.h", and if "A.h" looks like:
#include "B.h"
#once
Then "A.h" can get included multiple times. For this reason
(and others) it is suggested that the #once directive be put on the
first line of any include file in which it appears.
Also included in the patch-kit are two related extensions which
may make working with inline functions/methods easier. The first
of these is the capability to use relational operators on string
values in preprocessor conditional commands (e.g. #if). The second
feature is the __BASE_FILE__ builtin symbol. This symbol is always
defined (like __FILE__) to a string literal value. It is only
defined once however at the start of each compilation, and it's
value remains the same even while include files are being processed.
These two features can be used together to make it easy to alternately
enable or disable the inlining of certain functions (or methods) whose
definitions appear in include files.
Specifically, consider the following include file:
sample.H
-----------------------------------------------------------------------
#include "other_stuff.H"
#if INLINING || (__BASE_FILE__ == "sample.C")
INLINE int dialing_for_dollars (int count, int amount)
{
if (count == tv_count && amount == tv_amount)
return winner;
else
return loser;
}
#endif
-----------------------------------------------------------------------
If this file is included into a compilation for which the following
defines are given:
-DINLINING -DINLINE=inline
The the function "dialing_for_dollars" will be inlined. If however, the
compilation options are:
-UINLINING -DINLINE=
Then the function definition will effectively vanish, except when
the base file is the file "sample.C".
This is good, because if you do *not* want to inline the given
routine, then it should vanish in most compilations, but you still
need to have its source code present in one "home" compilation
so that the (one and only) out-of-line version of the routine
gets generated.
--
// Ron Guilmette - MCC - Experimental (parallel) Systems Kit Project
// 3500 West Balcones Center Drive, Austin, TX 78759 - (512)338-3740
// ARPA: rfg@mcc.com
// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg
gsf@ulysses.homer.nj.att.com (Glenn Fowler[drew]) (03/20/89)
In article <124@riunite.ACA.MCC.COM>, rfg@riunite.ACA.MCC.COM (Ron Guilmette) writes: > As someone pointed out recently, the subject of multiple > inclusion of individual include files was beaten to death > here not long ago. > At the risk of starting it all up again, I would like to > announce the availability of patches for the the GNU C > preprocessor (version 1.34) which implement the new #once > directive. These patches may be aquired by simply sending > me mail and requesting the patches. I hope that these patches > will soon become a standard part of the GNU releases, but till > then, I will distribute them. implementing #once as #pragma once would be more in line with the current standards efforts since #pragma's may/must be ignored by certain implementations the paradigm would be #ifndef <magic_symbol> #define <magic_symbol> #pragma once ... #endif this would allow for: (1) portability -- works for all implementations that either ignore #pragma's or that implement once (2) efficiency for those implementations that implement once (3) compatibility with those implementations that implement the equivalent of once by detecting #ifndef...#endif wrapped include files (4) correctness for any errors/choices in the file identity algorithm (excuse the os-dependent examples): ln a.h b.h # "a.h" == "b.h" ? ln -s a.h b.h # "a.h" == "b.h" ? cd /tmp echo '' > stdio.h echo '#include "stdio.h"' > a.c echo '#include <stdio.h>' >> a.c # "stdio.h" == <stdio.h> ? # "./a.h" == "a.h" ? # "$PWD/a.h" == "./a.h" ? (where $PWD really expanded) note that with NFS and RFS the same physical file accessed by different paths may have different <dev,ino> -- Glenn Fowler (201)-582-2195 AT&T Bell Laboratories, Murray Hill, NJ uucp: {att,decvax,ucbvax}!ulysses!gsf internet: gsf@ulysses.att.com
rfg@riunite.ACA.MCC.COM (Ron Guilmette) (03/21/89)
In article <11338@ulysses.homer.nj.att.com> gsf@ulysses.homer.nj.att.com (Glenn Fowler[drew]) writes: >In article <124@riunite.ACA.MCC.COM>, rfg@riunite.ACA.MCC.COM (Ron Guilmette) writes: > >implementing > #once >as > #pragma once >would be more in line with the current standards efforts >since #pragma's may/must be ignored by certain implementations See my comments in another recent posting. I think this is a *bad* idea. >this would allow for: >(4) correctness for any errors/choices in the file identity > algorithm (excuse the os-dependent examples): > note that with NFS and RFS the same physical file accessed > by different paths may have different <dev,ino> I intentionaly left loopholes in the way #once is implemented. If you want and/or need to circumvent it, you can easily do so by simply making multiple links (hard or symbolic) to a given include file, and then using different pathnames to include the file. The point about NFS/RFS and inodes is *not* relevant, because the ommission of re-included #once files is done of the basis of remembered pathnames, not on the basis of remembered inode numbers. The reason for this is simple. Some systems (e.g. VMS, MS-DOS) may not support the concept of inodes. Thus, using pathnames should be more portable. -- // Ron Guilmette - MCC - Experimental (parallel) Systems Kit Project // 3500 West Balcones Center Drive, Austin, TX 78759 - (512)338-3740 // ARPA: rfg@mcc.com // UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg
henry@utzoo.uucp (Henry Spencer) (03/22/89)
In article <124@riunite.ACA.MCC.COM> rfg@riunite.UUCP (Ron Guilmette) writes: >... patches for the the GNU C >preprocessor (version 1.34) which implement the new #once >directive... >The semantics of the #once directive are simple. The #once >directive causes any file it appears in to be included no more >than one time during any given individual compilation... Was it really necessary to invent a new directive for this? The existing construct: #ifndef gorble_h #define gorble_h 1 ... #endif suffices. Patches to the compiler to recognize *this* construct in an include file, and optimize out future references to that file, would do the same job and be 100% compatible with both existing practice and existing standardization efforts. #once is neither. -- Welcome to Mars! Your | Henry Spencer at U of Toronto Zoology passport and visa, comrade? | uunet!attcan!utzoo!henry henry@zoo.toronto.edu