Topic: Non-leaking include ( was Enum member functions (was C++0x))


Author: scotts@ims.com (Scott Schurr)
Date: Wed, 9 May 2001 17:59:39 CST
Raw View
In article <3AF983A4.8FEEE89E@jps.net>, Dennis Yelle <dennis51@jps.net> writes:
|> Scott Schurr wrote:
|> [...]
|> > An example where is is useful is when class Alpha declares a public
|> > enum, but another class (Beta) wants to carry an enum of that value.
|> > Today, the header of class Beta must include the header of class
|> > Alpha - which exposes Alpha to all users of Beta.  If Beta could
|> > forward declare the enum (with sufficient size information), then
|> > Beta's header could declare storage for the enum without including
|> > Alpha's header.
|>
|> That is a very general problem, not restricted to emuns.
|>
|> A header X should be allowed to include another header Y
|> without the stuff in Y "leaking" out into the file
|> that included X.
|>
|> I don't have any guess about what would be the best
|> way to achieve this.  Do you?

Solving the general problem?  No, I don't know a good
general solution.  And I don't know what could be added
to C++ to help.

As C++ stands today, I make a serious effort to exclude #include
files from my headers.  I do that using two techniques:

 1. I use forward declarations in header files instead of
    #includes whenever possible.  If the header only needs
    to know the name, and not the inner workings, of a class
    this often works.

 2. I push my #includes into my implementation files.  Since
    the implementation file never gets #included by another
    file there are no leaks from here.

Sometimes it's not possible to leave a #include out of a header.
Then you just have to live with the leak.  Things that can't
be forward declared, like enums and typedefs are one instance.
And if the enum is a member of a class, then you have to #include
the entire class declaration.

Another instance of something that requires a #include is using
anything from the standard library, like vector or map.  Elements
of the standard library are often typedefs of some implementation
determined template.  If you forward declare these then you lose
any hope of portability -- even to the next version of the same
compiler.

Another way to reduce #include leaks is to use the pimpl idiom.
That adds other overhead to the code, which the previous
suggestions do not.  But if the information leak is important
sometimes its justified.  There are also other good reasons
to use the pimpl idiom.

I'm no guru, and I'm sure the hot shots around here will have
other suggestions.

I hope that helps.

Regarding Dennis's question about a general solution for
leaking #includes...

Er, here's a boneheaded idea.  If #includes were scoped -- yes,
I know that we're running the preprocessor -- so the #included
stuff disappeared when you left scope, then you could prevent
#include leakage.  Let's say you have a class that has map
as a member.  You #include <map> *inside* the braces for the
class, so the class knows about maps.  As soon as you leave the
braces of the class, knowledge about map goes out of scope...

Wow.  Don't ask me to write a compiler with behavior like that.

And, please, no flames of rocks or anything.  We're supposed
to brainstorm, remember?...

--------------------------------------
Scott Schurr
  Integrated Measurement Systems, Inc.
  Voice: (503) 626-7117
  Fax:   (503) 644-6969
  Email: scotts@ims.com
--------------------------------------

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Dennis Yelle <dennis51@jps.net>
Date: Wed, 9 May 2001 20:48:56 GMT
Raw View
Scott Schurr wrote:
[...]
> An example where is is useful is when class Alpha declares a public
> enum, but another class (Beta) wants to carry an enum of that value.
> Today, the header of class Beta must include the header of class
> Alpha - which exposes Alpha to all users of Beta.  If Beta could
> forward declare the enum (with sufficient size information), then
> Beta's header could declare storage for the enum without including
> Alpha's header.

That is a very general problem, not restricted to emuns.

A header X should be allowed to include another header Y
without the stuff in Y "leaking" out into the file
that included X.

I don't have any guess about what would be the best
way to achieve this.  Do you?

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]