Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why only external linkage for template params?

140 views
Skip to first unread message

Raoul Gough

unread,
Aug 28, 2002, 7:50:04 PM8/28/02
to
I've been wondering why the standard requires template parameters to
have external linkage. For instance, if I have:

void foo ()
{
class foo_local { /* local class ... */ };

std::vector<foo_local> foo_local_vector; // Illegal
// use vector...
}

assuming that the relevant definitions for std::vector are available,
the instance std::vector<foo_local> could just be compiled into the
current module and given internal linkage (matching its parameter's
linkage). I think a lot of compilers already compile template into the
same object file, and the external linkage allows the linker to
eliminate multiple copies of the same instance. Obviously that's not
an issue when a parameter has internal linkage, since its impossible
to duplicate that instance in another module.

I suspect that the existing restriction has to do with allowing for
separate compilation of templates and/or repository-based schemes.
However, I would have thought that a compiler or linker could produce
the same effect as internal linkage by use of the additional
information that they must already have (such as the name and location
of the object file requiring the instance).

So why can't template parameters with internal-linkage simply force
the instance itself to have internal linkage also?

Regards,
Raoul Gough.


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

James Kanze

unread,
Aug 30, 2002, 11:55:11 PM8/30/02
to
"Raoul Gough" <Raoul...@yahoo.co.uk> wrote in message
news:<akjl0u$1j8827$1...@ID-136218.news.dfncis.de>...

> I've been wondering why the standard requires template parameters to
> have external linkage. For instance, if I have:

> void foo ()
> {
> class foo_local { /* local class ... */ };
>
> std::vector<foo_local> foo_local_vector; // Illegal
> // use vector...
> }

> assuming that the relevant definitions for std::vector are available,
> the instance std::vector<foo_local> could just be compiled into the
> current module and given internal linkage (matching its parameter's
> linkage). I think a lot of compilers already compile template into the
> same object file, and the external linkage allows the linker to
> eliminate multiple copies of the same instance. Obviously that's not
> an issue when a parameter has internal linkage, since its impossible
> to duplicate that instance in another module.

> I suspect that the existing restriction has to do with allowing for
> separate compilation of templates and/or repository-based schemes.
> However, I would have thought that a compiler or linker could produce
> the same effect as internal linkage by use of the additional
> information that they must already have (such as the name and location
> of the object file requiring the instance).

I suspect that the original motivation was linked to the way CFront
instantiated templates. But there are also arguments concerning
visibility, etc. The template class is defined in global scope. I
suspect that the distinction between dependant and non-dependant names
weakens this argument considerably. And I wouldn't be too surprised if
this restriction were lifted in a future version of C++.

--
James Kanze mailto:jka...@caicheuvreux.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung

Vishal Kochhar

unread,
Sep 9, 2002, 2:59:23 PM9/9/02
to

Raoul Gough wrote:

> I've been wondering why the standard requires template parameters to
> have external linkage. For instance, if I have:
>
> void foo ()
> {
> class foo_local { /* local class ... */ };
>
> std::vector<foo_local> foo_local_vector; // Illegal
> // use vector...
> }
>

Even though function represents scope, it can not be used in qualifying a
name. Imagine if local classes were allowed as template argument, what would
be T in the following for above scenario:

template <class T, class ...> class vector {
T* t_; //T is foo::foo_local?
//.......................
};

Vishal

Anthony Williams

unread,
Sep 10, 2002, 11:42:49 AM9/10/02
to
vcmpk--...@yahoo.com (Vishal Kochhar) writes:

> Raoul Gough wrote:
>
> > I've been wondering why the standard requires template parameters to
> > have external linkage. For instance, if I have:
> >
> > void foo ()
> > {
> > class foo_local { /* local class ... */ };
> >
> > std::vector<foo_local> foo_local_vector; // Illegal
> > // use vector...
> > }
> >
>
> Even though function represents scope, it can not be used in qualifying a
> name. Imagine if local classes were allowed as template argument, what would
> be T in the following for above scenario:
>
> template <class T, class ...> class vector {
> T* t_; //T is foo::foo_local?
> //.......................
> };

That is no reason to ban it --- it could work the same way as anonymous
namespaces: there is a name which encodes the function name (so foo_local
declared in two different functions yields different classes), but you cannot
utter it in code, only the compiler knows what it is.

See my paper at
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1353.html

Anthony

Raoul Gough

unread,
Sep 10, 2002, 11:43:11 AM9/10/02
to
"Vishal Kochhar" <vcmpk--...@yahoo.com> wrote in message
news:3D78D978...@yahoo.com...

>
> Raoul Gough wrote:
>
> > I've been wondering why the standard requires template parameters
to
> > have external linkage. For instance, if I have:
> >
> > void foo ()
> > {
> > class foo_local { /* local class ... */ };
> >
> > std::vector<foo_local> foo_local_vector; // Illegal
> > // use vector...
> > }
> >
>
> Even though function represents scope, it can not be used in
qualifying a
> name.

The name is inaccessible *to the programmer* from outside the defining
scope. However, the compiler must have some internal means of
referring to it and keeping it separate from the same name in other
scopes.

> Imagine if local classes were allowed as template argument, what
would
> be T in the following for above scenario:
>
> template <class T, class ...> class vector {
> T* t_; //T is foo::foo_local?
> //.......................
> };

The compiler already has to deal with a similar problem:

void foo () {
static int callCount = 0;
}

void bar () {
static int callCount = 0;
}

Here are two different static variables, both called "callCount"
within their scopes, which require separate storage space. So what are
the "names" of the two separate int variables? If foo and bar were
classes, the variables would be referencable within the code as
foo::callCount and bar::callCount, but (as you point out) function
names cannot be used as qualifiers. However, the compiler still has to
keep them separate internally. One option is simply to create separate
symbols like foo__callCount and bar__callCount, which are known to the
compiler but unknown to the programmer (note the double underscores,
which make these reserved names).

So, although the language does not provide a way of referring to names
local to another function scope, the compiler must be able internally
to keep the names distinct. The only problem with applying this to
template parameters is that function-local names currently have
internal linkage, and template parameters must currently have external
linkage (which is the bit I was originally asking about).

Regards,
Raoul Gough.

0 new messages