[comp.lang.c++] precompiling header files

tmb@AI.MIT.EDU (Thomas M. Breuel) (08/08/90)

|Also, would ``dump'' and ``undump'' be appropriate for building e.g.,
|a preload version of g++ that ``knows'' everything about libg++
|interfaces? Is there a possibility that this mechanism would be
|extended, i.e., when you process a file and read class interfaces
|(.h), you write data into a specific file (the interface file, which
|might be per-user) using some DBM/GDBM structure with a timestamp.
|Then, compare the timestamp to the .h timestamp, and if .h is not new,
|load the data from the database rather than via parsing the .h file.
|I assume this could even hold e.g., inline definitions, like
|dump/undump does?

I think we will ultimately need a separate output file from each
compilation: the ".o" file contains the binary code, and another file,
say, ".g", contains additional type checking, inlining, template, and
debugging information in some format that can be loaded quickly
by the compiler. If you compile a header file (something that
generates no code), you would just get back the ".g" file. Another
choice would be to put this information directly into the ".o" file
(say, into a "comment" section).

There are several possible ways in which ".g" files might be used.  The
cleanest way would be to add a new keyword to the language, something
like "use", that would look for, and use, a ".g" file.  Note, in
particular, that making "use" a language feature and not a
pre-processor feature would encourage the use of inline functions,
templates, and "const" data over pre-processor hacks. 

However, modifications to the C pre-processor are also possible that
would take advantage of ".g" files transparently, but this would mean
that one would also have to address the question of how to put
pre-processor information into the ".g" file. I don't think that
would be a good idea, though: the gain from pre-processing header
files comes from the pre-parsing of declarations, not from the
pre-parsing of a few "#define" directives. Furthermore, the utility
of cpp in C++ is rather limited anyway, given that almost all
of its classic purposes have been taken over by some C++ feature.

".g" files would also allow you to use a different programming
style and free you from the need of duplicating many declarations.
Currently, if you want a function to be compiled but do not want its
source code included into every compilation unit that uses it, you must
put a declaration into a header file, and repeat the declaration (as
part of the definition) in the implementation part.  This redundancy is
a source of static errors and requires quite a bit of effort keeping
two separate files (or parts of a file) consistent. After all, the
source code already states clearly whether a particular object is local
to the file (static), or local to a class (private/protected).

In summary, I think trying to support the semantics of ".h" files
transparently in the presence of pre-parsing isn't worth the effort.
Supporting something like the ".g" files described above would allow you
to write new code that works both with compilers that support and
that don't support the feature. Existing code could be converted
easily to take advantage of the new feature by separating pre-processor
"#defines" into a separate header file, possibly with the help
of some utility. 

".g" files provide a more efficient solution for several new
language features, such as inlining and templates, and some
mechanism like it is certainly needed soon.

					Thomas.

rfg@NCD.COM (Ron Guilmette) (08/09/90)

This is only a test message.  tmb, please reply.

-- 

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.

gwu@nujoizey.tcs.com (George Wu) (08/09/90)

In article <9008080109.AA03748@lem>, tmb@AI.MIT.EDU (Thomas M. Breuel) writes:
|> ".g" files would also allow you to use a different programming
|> style and free you from the need of duplicating many declarations.
|> Currently, if you want a function to be compiled but do not want its
|> source code included into every compilation unit that uses it, you must
|> put a declaration into a header file, and repeat the declaration (as
|> part of the definition) in the implementation part.  This redundancy is
|> a source of static errors and requires quite a bit of effort keeping
|> two separate files (or parts of a file) consistent. After all, the
|> source code already states clearly whether a particular object is local
|> to the file (static), or local to a class (private/protected).

     What's wrong with including the header file in the implementation
source as well?  Then the compiler will see any inconsistency between
the header and the implementation.

						George


----
George J Wu                           | gwu@tcs.com or ucbcad!tcs!gwu
Software Engineer                     | 2121 Allston Way, Berkeley, CA, 94704
Teknekron Communications Systems, Inc.| (415) 649-3752

jmd@dlogics.COM (Jens M. Dill) (08/10/90)

In article <946@tcs.tcs.com>, gwu@nujoizey.tcs.com (George Wu) writes:
> In article <9008080109.AA03748@lem>, tmb@AI.MIT.EDU (Thomas M. Breuel) writes:
> |> Currently, if you want a function to be compiled but do not want its
> |> source code included into every compilation unit that uses it, you must
> |> put a declaration into a header file, and repeat the declaration (as
> |> part of the definition) in the implementation part.  This redundancy is
> |> a source of static errors and requires quite a bit of effort keeping
> |> two separate files (or parts of a file) consistent.
> 
>      What's wrong with including the header file in the implementation
> source as well?  Then the compiler will see any inconsistency between
> the header and the implementation.

What's "wrong" is that what appears in the header file must be a DECLARATION,
but what appears in the source file must be a DEFINITION.  You still have to
maintain two independent copies of the same information (type, storage class,
prototype, etc.)  An explicit or implicit EXPORT facility that collected
declaration information by reading the external definitions in a source file
would be a big convenience.

*=====* TIME CANNOT BE WASTED *=====*       -- Jens M. Dill
 \ But it can be used for purposes /           jmd@dlogics.com
  \ other than what was intended. /
   *=============================*

gwu@nujoizey.Berkeley.EDU (George Wu) (08/15/90)

In article <617@dlogics.COM>, jmd@dlogics.COM (Jens M. Dill) writes:
|> In article <946@tcs.tcs.com>, gwu@nujoizey.tcs.com (George Wu) writes:
|> > In article <9008080109.AA03748@lem>, tmb@AI.MIT.EDU (Thomas M.
Breuel) writes:
|> > |> Currently, if you want a function to be compiled but do not want its
|> > |> source code included into every compilation unit that uses it, you must
|> > |> put a declaration into a header file, and repeat the declaration (as
|> > |> part of the definition) in the implementation part.  This redundancy is
|> > |> a source of static errors and requires quite a bit of effort keeping
|> > |> two separate files (or parts of a file) consistent.
|> > 
|> >      What's wrong with including the header file in the implementation
|> > source as well?  Then the compiler will see any inconsistency between
|> > the header and the implementation.
|> 
|> What's "wrong" is that what appears in the header file must be a
DECLARATION,
|> but what appears in the source file must be a DEFINITION.

     I was aware of the difference.  You can also have the declaration in
the source file.

|> You still have to
|> maintain two independent copies of the same information (type,
storage class,
|> prototype, etc.)  An explicit or implicit EXPORT facility that collected
|> declaration information by reading the external definitions in a source file
|> would be a big convenience.

     There may be two copies of the interface definition, but the compiler
will automatically check them for consistency.  I'm not arguing the
"philisophical" merits of an export facility.  I am stating that given what
features we do have, I do not find such maintenance activity to be of almost
no effort, certainly not when compared to the task of converting all the
consumers of a library to something that has just changed its interface.

							George

----
George J Wu                           | gwu@tcs.com or ucbcad!tcs!gwu
Software Engineer                     | 2121 Allston Way, Berkeley, CA, 94704
Teknekron Communications Systems, Inc.| (415) 649-3752