Topic: The new export keyword


Author: David Vandevoorde <daveed@cup.hp.com>
Date: 1998/02/06
Raw View
(I posted this earlier, but I'm afraid my local NNTP
 server is misconfigured.)

B.Mohr wrote:
[...]
> I checked the new Stroustrup, 3rd edition, but he only
> writes 1 sentence about "export". I also checked some
> WWW sites and articles in the C++ Report, but couldn't
> find anything.

The dearth on information on the subject could be due
to the lack of any implementation experience yet, or
simply because it's a not-so-easy topic ;-)

The export keyword is a notification to the compiler
that the definition of a function template, member
function of a class template, member function template
or static data-member template should be made available
to other translation units (TUs) that _declare_ the
template and create a point of instantiation for one of
its  (implicit) specializations without the need for
explicit inclusion of the template _definition_. Tagging
a class with `export' means all exportable members are
exported.

E.g.:

        // file_1.C:
        template<typename T>
        void f(); // template declaration, but no definition

        int main() {
           f<int>();
        }
        // <- point of instantiation for f<int>()



        // file_2.C
        #include <stdio.h>

        export template<typename T>
        void f() {
           printf("Hello World!");
        }

The two TUs together form a valid C++ program (I think ;-).
Note how file_1.C does not contain the definition of the
template `f' for which it creates a point of instantiation.

This is the essence of the so-called ``separation model''
(as opposed the ``inclusion model'' a variant of which is
 implemented by most commercial compilers.)

What makes the use of exported templates so hard, is the
issue of ``transitive instantiation points'': points of
instantiation created by the instantiation process itself.
For example:

        template<typename T> void a(T) {}

        template<typename T> void b(T) { a(1); }

        int main() {
           b(0);
        }

        // <- point of instantiation for b<int>(int)
        //    and transitively a<int>(int).

The instantiation of b<int>(int) calls for the instantiation
of a<int>(int). The question that may perhaps not be obvious
in the above example is:

        ``which declarations are visible
          while instantiating a<int>(int)?''

A set of visible declarations is referred to as ``a context''
(only declarations with external linkage count, really).

Ideally, you'd want the context for the instantiation of
a<int>(int) to be a sort of combination of the context
when the template `a<T>' was defined and the context at
the point of instantiation of `a<int>(int)'.

(Note that there could be multiple points of instantiation
for a single specialization: all must be equivalent --- it's
the user's responsibility to ensure that --- no diagnostic
required).

In the ``inclusion model'' you almost get that ``sort of
combination'' for free: the template definition occurred
earlier in the TU (wrt. to the point of instantiation).
Argument-dependent lookup (aka. Koenig lookup) ensures
that the instantiation process presumably also picks up
bits and pieces that were enclosed in namespaces.

A semantic disadvantage of this ``inclusion model'' however
is that the context of instantiation might be crowded with
declarations that have nothing to do with the intended
specialization.

With exported templates OTOH the ``combined context''
no longer comes for free since the declarations visible
where the template is defined are not necessarily visible
where the template is instantiated: the two may be in
separate TUs. In fact, it's quite hard to come up with a
specification for this context that is both efficiently
implementable _and_ useful. The solution eventually chosen
for C++ was to avoid the synthesis of a ``combined context''
and instead have transitive instantiation points ``stick''
to the primary instantiation points that created them.

This puts some (relatively strong, I think) restrictions
on the definitions of the transitively instantiated
template since they cannot refer to declarations not
visible in the other context. More precisely, they cannot
do so with dependent names (non-dependent names are bound
at template-definition time and are therefore not a
problem).

Hmm... I tried to be brief, but as I said ``it's a
not-so-easy topic''.

        Daveed
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: msherman@magma.ca (Marc Sherman)
Date: 1998/02/06
Raw View
In article <34DABC5F.532AC8D6@cup.hp.com>,
David Vandevoorde  <daveed@cup.hp.com> wrote:
>This puts some (relatively strong, I think) restrictions
>on the definitions of the transitively instantiated
>template since they cannot refer to declarations not
>visible in the other context. More precisely, they cannot
>do so with dependent names (non-dependent names are bound
>at template-definition time and are therefore not a
>problem).
>
>Hmm... I tried to be brief, but as I said ``it's a
>not-so-easy topic''.

You were certainly right about that last bit, David.  Could you possibly
give an example of a type-dependent name usage that is illegal in an
exported template?  How would this kind of thing fail - an error while
resolving a name, or would it actually bind a name to the wrong type?

- Marc



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: zdv176@zam368.zam.kfa-juelich.de (B.Mohr)
Date: 1998/01/28
Raw View
Hi,
I am wondering, if anybody could write me a paragraph or two about how the
new "export" keyword is supposed to be used (or point me to a WWW page or
article)? A small example would be nice too.

I checked the new Stroustrup, 3rd edition, but he only writes 1 sentence
about "export". I also checked some WWW sites and articles in the C++
Report, but couldn't find anything.

Thanks
Bernd

P.S. I guess I could read the draft standard, but I have a hard time
     understanding the standard language.
--
Bernd Mohr / Research Centre Juelich, ZAM, Germany / B.Mohr@fz-juelich.de
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]