Topic: Linkage of friends of templates ... continued.
Author: jhl@sssonline.com (Jonathan H Lundquist)
Date: Tue, 24 Jun 2003 17:18:34 +0000 (UTC) Raw View
> Scott Meyers wrote:
>
> <Scott begin>
> Suppose I have a class template that declares a friend function that
> is
> completely defined within the template, e.g.,
>
> template<typename T>
> class rational {
>
> friend bool operator>(const rational& lhs, const rational& rhs)
> { return true; }
>
> };
>
> Since each operator> is a non-template non-member function, I'm assume
> that
> each has external linkage. In practice, however, with the two
> compilers I
> have working here (g++ 3.2 and VC 7.1), I find that if I compile
> multiple
> translation units such that a particular operator> function is used in
> both, I can link the two object files together and not get any kind of
> complaint about a multiply defined system. That suggests that maybe
> each
> operator> function has internal linkage. So, as usual, I'm confused.
>
> Questions:
> 1. What kind of linkage does each operator> have?
> 2. Where is that specified in the standard?
> 3. If the linkage is external, why am I not getting a link-time
> error
> in my simple experiments? I have already verified that each
> object
> file I'm linking has its own externally visible copy of the
> function.
> </Scott end>
1. I believe it has external linkage, just as any other inline
definition of a function would.
2. Section 3.5 says (with caveats) essentially that a function that
doesn't explicitly have internal linkage has external linkage.
3. Section 7.1.2/4 requires the build system to make it work. In the
case of PE files this is done with a special segment type (comdat?)
which the linker knows to merge duplicate symbols from. I assume COFF
files have something similar. Whatever the platform, the standard
specifies the build system must merge the duplicates.
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: google@vandevoorde.com (Daveed Vandevoorde)
Date: Thu, 26 Jun 2003 01:43:13 +0000 (UTC) Raw View
dhruvbird@gmx.net (Dhruv) wrote:
[...]
> Scott Meyers wrote:
>
> <Scott begin>
> Suppose I have a class template that declares a friend function that
> is
> completely defined within the template, e.g.,
>
> template<typename T>
> class rational {
>
> friend bool operator>(const rational& lhs, const rational& rhs)
> { return true; }
>
> };
>
> Since each operator> is a non-template non-member function, I'm assume
> that each has external linkage.
Indeed.
> In practice, however, with the two compilers I
> have working here (g++ 3.2 and VC 7.1), I find that if I compile
> multiple
> translation units such that a particular operator> function is used in
> both, I can link the two object files together and not get any kind of
> complaint about a multiply defined system. That suggests that maybe
> each operator> function has internal linkage. So, as usual, I'm confused.
Actually, the fact that the function appears in a template need not
be relevant. More relevant is that since the definition appears in
the class, the function is implicitly inline, and you've probably been
defining (extern) inline functions in multiple translation units for
quite a while without trouble. (There is an ODR exemption for inline
functions.)
> Questions:
> 1. What kind of linkage does each operator> have?
External linkage and extern "C++" name linkage.
> 2. Where is that specified in the standard?
3.5/4 is the main item.
> 3. If the linkage is external, why am I not getting a link-time
> error in my simple experiments? I have already verified that each
> object file I'm linking has its own externally visible copy of the
> function.
See above: It's an inline function. Often this is achieved using
COMDAT object file sections.
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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dhruvbird@gmx.net (Dhruv)
Date: Tue, 24 Jun 2003 01:45:55 +0000 (UTC) Raw View
A link to the actual thread:
http://groups.google.com/groups?dq=&hl=en&lr=&ie=UTF-8&safe=off&threadm=d2o0bv4ooonluag9h7msul2dtjdtke7345%404ax.com&prev=/groups%3Fdq%3D%26num%3D25%26hl%3Den%26lr%3D%26ie%3DUTF-8%26group%3Dcomp.std.c%252B%252B%26safe%3Doff%26start%3D100
Scott Meyers wrote:
<Scott begin>
Suppose I have a class template that declares a friend function that
is
completely defined within the template, e.g.,
template<typename T>
class rational {
friend bool operator>(const rational& lhs, const rational& rhs)
{ return true; }
};
Since each operator> is a non-template non-member function, I'm assume
that
each has external linkage. In practice, however, with the two
compilers I
have working here (g++ 3.2 and VC 7.1), I find that if I compile
multiple
translation units such that a particular operator> function is used in
both, I can link the two object files together and not get any kind of
complaint about a multiply defined system. That suggests that maybe
each
operator> function has internal linkage. So, as usual, I'm confused.
Questions:
1. What kind of linkage does each operator> have?
2. Where is that specified in the standard?
3. If the linkage is external, why am I not getting a link-time
error
in my simple experiments? I have already verified that each
object
file I'm linking has its own externally visible copy of the
function.
</Scott end>
Victor Bazarov wrote:
<Victor begin>
No references to a template class are passed anywhere. When time
comes to pass references, there are no template classes. Both
types are specialised due to implicit instatiation.
MHO is that it's a special case. It's not a template because
there are no template arguments defined for that function (and
it cannot make use of 'T', can it?*) and unlike the real templates,
this function cannot be explicitly instantiated or specialised.
It is a template in the sense that when needed it is imlicitly
instantiated with concrete types. But it's not fully a template
like the class or its members are.
*) The scope of a friend function defined in the class definition
is the namespace of the class, so no names declared in the class
are available in the function directly.
</Victor end>
14.5.3p1
"A friend function of a class template can be a function template or
an
ordinary (non-template) function. [Example:
template<class T> class task {
// ...
friend void next_time();
friend task<T>* preempt(task<T>*);
friend task* prmt(task*); // task is task<T>
//NOTE.
friend class task<int>;
// ...
};"
Does this also apply to friend functions DEFINED within the template
class scope?
If it does, then rational is actually rational<T>. If not, then Victor
is probably right.
14.5.3p3
"3 When a function is defined in a friend function declaration in a
class
template, the function is defined when the class template is
first
instantiated. The function is defined even if it is never
used.
[Note: if the function definition is ill-formed for a given
special-
ization of the enclosing class template, the program is
ill-formed
even if the function is never used. --end note]"
This doesn't help much though.
Regards,
-Dhruv.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]