Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-04-15 09:07:14


"Paul Mensonides" <pmenso57_at_[hidden]> writes:

> None of these extensions are without precedent or are major extensions--except a
> scoping mechanism, which I added because what I've seen of the current idea is
> fundamentally flawed.

Here are some remarks I sent to David Vandevoorde after ruffling some
feathers in the extensions working group at the C++ committee meeting
by suggesting the same thing -- he offered to present some of them for
me to avoid misinterpretation. My original concerns were based around
PP metaprogramming but you will probably find the ones presented here
to be much more pedestrian. The notation and semantics below is based
on the last discussion I saw in the EWG, but I think the notation in
particular is still very fluid. BTW, I have some sympathy for the
idea of using scoping characters (like "{}") that can be matched by
existing editors.

---
How will macro scoping be used in real life?  Let's take a look at a
simple example.  Assume header x.hpp defines exported configuration
macros SOME_LIBRARY_X, SOME_LIBRARY_Y and SOME_LIBRARY_Z.  Suppose I
want to use that in a header a.hpp.  One possibility is:
a.hpp:
    #{
    # ifndef A_INCLUDE_GUARD
    #  define A_INCLUDE_GUARD
    #  include "x.hpp"
    #  in SOME_LIBRARY_X SOME_LIBRARY_Y SOME_LIBRARY_Z
       .
       .
       .
    # endif // A_INCLUDE_GUARD
    #}
I have a concern about the amount of boilerplate code here.  Now every
modern header file will have 3 lines of boilerplate at the beginning
and 2 at the end.  It would be nice to be able to write:
    #scope
(or something) at the beginning of the file, and have that be
equivalent to all of the boilerplate.
Another concern I have is that in order to avoid leaking the names
defined in x.hpp, the user of x.hpp must not only #include it, but
must explicitly "in" each of them.  For libraries which require quite
a few configuration macros, this can be terribly verbose.  It would be
nice to be able to just write:
    #include "x.hpp"
and get all of its exported macros in the current scope.  But how
would that work?  Let's look at x.hpp:
x.hpp
    #{
    # ifndef SOME_LIBRARY_X_INCLUDE_GUARD
    #  define SOME_LIBRARY_X_INCLUDE_GUARD
    #  include "z.hpp"
       .
       .        
       .
    #  define SOME_LIBRARY_X ...
    #  define SOME_LIBRARY_Y ...
    #  define SOME_LIBRARY_Z ...
       // here
    # endif // SOME_LIBRARY_X_INCLUDE_GUARD
    #}
You might think you could just add
    #  out SOME_LIBRARY_X SOME_LIBRARY_Y SOME_LIBRARY_Z
at the comment marked "here", but think about what happens in this
case:
b.hpp:
    #{
    # ifndef A_INCLUDE_GUARD
    #  define A_INCLUDE_GUARD
    #  include "x.hpp"
    #  in SOME_LIBRARY_X SOME_LIBRARY_Y SOME_LIBRARY_Z
       // use SOME_LIBRARY_X/Y/Z to define void foo(bar)
    # endif // A_INCLUDE_GUARD
    #}
c.hpp
    #{
    # ifndef A_INCLUDE_GUARD
    #  define A_INCLUDE_GUARD
    #  include "c.hpp"              // for void foo(bar)
    #  include "x.hpp"              // for config macros
    #  in SOME_LIBRARY_X SOME_LIBRARY_Y SOME_LIBRARY_Z
       .
       .
       .
    # endif // A_INCLUDE_GUARD
    #}
because of the #include guards in x.hpp, including it in c.hpp has no
effect.  Can the code in c.hpp see the SOME_LIBRARY_... config macros?
-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk