Topic: Templates and linkage, was What c++ compiliers are available for AIX


Author: jhs@edg.com (John H. Spicer)
Date: Thu, 27 Jan 1994 03:18:01 GMT
Raw View
In article <CK5JL0.wAA@hawnews.watson.ibm.com> jjb@watson.ibm.com (John Barton) writes:
>The example posted by Joachim Schrod raises important issues for the
>ANSI standard.  By reposting to comp.std.c++ I hope someone on the
>committee will consider this case.  Note that the explicit declaration
>that follows the inline template definition would, in the absence of
>the template, default to external linkage.  Were this explicit declaration
>preceded by an equivalent inline declaration, the function would have
>internal linkage, by default or even if it has "extern".  This seems
>to be a C-compatibility issue.  See ARM 3.3.  So: does the inline
>template change the explicit declaration to internal linkage?? (If
>so, the IBM xlC compiler is correct).
>
>If the template declaration does nothing to the linkage of the
>explicit declaration, then should the inline template definition
>be expanded for the extern explicit declaration?  I think the answer
>has to be No: once we have established that the function has external
>linkage the inline template cannot match.

Our compiler (the EDG C++ compiler) handles this case in the same way
as the IBM compiler.

What we do (and what I'm guessing the IBM compiler does) is recognize
that the declaration of "int compare(const A&, const A&)" is one of the
set of functions that could be generated by the template.  Once this
is recognized, the declaration is used to alter the way in which that
particular instance of the template is treated for overload resolution
purposes.  It is not considered to provide any information about whether
the actual definition of the function is to be supplied using the
template or not.

This example illustrates a problem that used to exist concerning the way
in which template functions could be specialized.  You could specialize
an out of line template with an inline user specialization, but the
reverse (specializing an inline template with an out of line user
specialization) was only possible in the file that defined the out
of line instance.

This problem was addressed in the 11/93 X3J16/WG21 meeting where a new
syntax for declaring specializations was adopted.  Using the new syntax
the declaration

 int compare<>(const A&, const A&);

can be used to specify that a user specialization of this function
is to be used instead of the template based version.  This new declaration,
unlike the old style, has no impact on how the template is considered for
overload resolution purposes.

The new specialization rules should make issues like this much easier
for programmers to deal with.

John Spicer
Edison Design Group
jhs@edg.com



>
>In article <2hj5nv$p7t@rs18.hrz.th-darmstadt.de>, schrod@iti.informatik.th-darmstadt.de (Joachim Schrod) writes:
>|> In article <CJunGq.oI5@hawnews.watson.ibm.com>, bhender@watson.ibm.com (Bruce Henderson) writes:
>|> >
>|> > But, I can tell you I have yet to find a problem
>|> > with the xlC compiler.
>|>
>|> Let me give you one... But that's a problem with g++, too (at least,
>|> it was for 2.4.5).
>|>
>|> Of course, if anybody tells me that our reading of the ARM is false,
>|> my apologies in advance. :) Btw, if you delete the `inline' specifier
>|> below, it works.
>|>
>|> Cheers,
>|>  Joachim
>|>
>|> ---------------- included file follows:
>|> // templatetest.C:
>|> //
>|> // The following program demonstrates a bug in xlC. A non-template
>|> // function has precedence over a template function. The declaration
>|> // of compare(const A&,const A&) is an exact match for the function
>|> // call in main (see ARM 14.4), but xlC inserts a call to the template
>|> // function.
>|> //
>|> // To demonstrate the bug, compile this file with
>|> //   xlC -o templatetest templatetest.C
>|> // If the compilation fails due to an unresolved reference (compare),
>|> // xlC is OK. Otherwise it used the template function and the executable
>|> // will fail at the assertion.
>|>
>|> #include <assert.h>
>|>
>|> template <class T>
>|> inline int compare(const T&, const T&)
>|> {
>|>   assert(0);
>|>   return 0;
>|> }
>|>
>|> class A {
>|>   int x;
>|>  public:
>|>   A() { x = 0; }
>|> };
>|>
>|> // declare a real compare function for class A
>|> int compare( const A& a, const A& b );
>|>
>|> int main( int argc, char **argv )
>|> {
>|>   A a1;
>|>   A a2;
>|>
>|>   // following compare must not call the template function
>|>   compare( a1, a2 );
>|> }
>|>
>|> ---------------- snip snap ----------------
>|>
>|> --
>|> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>|> Joachim Schrod   Email: schrod@iti.informatik.th-darmstadt.de
>|> Computer Science Department
>|> Technical University of Darmstadt, Germany
>
>--
>John.
>
>John J. Barton        jjb@watson.ibm.com            (914)784-6645
>H1-C13 IBM Watson Research Center P.O. Box 704 Hawthorne NY 10598






Author: jjb@watson.ibm.com (John Barton)
Date: Mon, 24 Jan 1994 20:58:12 GMT
Raw View
The example posted by Joachim Schrod raises important issues for the
ANSI standard.  By reposting to comp.std.c++ I hope someone on the
committee will consider this case.  Note that the explicit declaration
that follows the inline template definition would, in the absence of
the template, default to external linkage.  Were this explicit declaration
preceded by an equivalent inline declaration, the function would have
internal linkage, by default or even if it has "extern".  This seems
to be a C-compatibility issue.  See ARM 3.3.  So: does the inline
template change the explicit declaration to internal linkage?? (If
so, the IBM xlC compiler is correct).

If the template declaration does nothing to the linkage of the
explicit declaration, then should the inline template definition
be expanded for the extern explicit declaration?  I think the answer
has to be No: once we have established that the function has external
linkage the inline template cannot match.

In article <2hj5nv$p7t@rs18.hrz.th-darmstadt.de>, schrod@iti.informatik.th-darmstadt.de (Joachim Schrod) writes:
|> In article <CJunGq.oI5@hawnews.watson.ibm.com>, bhender@watson.ibm.com (Bruce Henderson) writes:
|> >
|> > But, I can tell you I have yet to find a problem
|> > with the xlC compiler.
|>
|> Let me give you one... But that's a problem with g++, too (at least,
|> it was for 2.4.5).
|>
|> Of course, if anybody tells me that our reading of the ARM is false,
|> my apologies in advance. :) Btw, if you delete the `inline' specifier
|> below, it works.
|>
|> Cheers,
|>  Joachim
|>
|> ---------------- included file follows:
|> // templatetest.C:
|> //
|> // The following program demonstrates a bug in xlC. A non-template
|> // function has precedence over a template function. The declaration
|> // of compare(const A&,const A&) is an exact match for the function
|> // call in main (see ARM 14.4), but xlC inserts a call to the template
|> // function.
|> //
|> // To demonstrate the bug, compile this file with
|> //   xlC -o templatetest templatetest.C
|> // If the compilation fails due to an unresolved reference (compare),
|> // xlC is OK. Otherwise it used the template function and the executable
|> // will fail at the assertion.
|>
|> #include <assert.h>
|>
|> template <class T>
|> inline int compare(const T&, const T&)
|> {
|>   assert(0);
|>   return 0;
|> }
|>
|> class A {
|>   int x;
|>  public:
|>   A() { x = 0; }
|> };
|>
|> // declare a real compare function for class A
|> int compare( const A& a, const A& b );
|>
|> int main( int argc, char **argv )
|> {
|>   A a1;
|>   A a2;
|>
|>   // following compare must not call the template function
|>   compare( a1, a2 );
|> }
|>
|> ---------------- snip snap ----------------
|>
|> --
|> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|> Joachim Schrod   Email: schrod@iti.informatik.th-darmstadt.de
|> Computer Science Department
|> Technical University of Darmstadt, Germany

--
John.

John J. Barton        jjb@watson.ibm.com            (914)784-6645
H1-C13 IBM Watson Research Center P.O. Box 704 Hawthorne NY 10598