egcs 1.0.1 bug
Adam P. Jenkins
ajenkins@cs.umass.edu
Fri Jan 9 10:59:00 GMT 1998
Gabriel Dos Reis writes:
> >>>>> ëAlexandreû, Alexandre Oliva <oliva@dcc.unicamp.br> wrote:
>
> Alexandre> Adam P Jenkins writes:
> >> it seems to crash when using explicit template
> >> arguments in a friend function declaration in a template class.
>
> Alexandre> That's because the template function must be declared before you refer
> Alexandre> to an specialization thereof. According to Mark Mitchell, this should
> Alexandre> be fixed with an appropriate error message in the next snapshot of
> Alexandre> egcs, so expect this to be fixed in the next release. The following
> Alexandre> declarations, before the template class body, would fix the problem:
>
> Alexandre> template <class T> class A;
> Alexandre> template <class T> A<T> foo(A<T>);
>
> This kind of question has become common. Isn't it a good
> candidate to be included in the FAQ ?
>
Part of the problem is that the warning message g++ gives when it
encounters a friend declaration in a template class is unclear.
Here's an example
--------------- tmp.cc ---------------
template <class T>
class A {
public:
friend A<T> foo(A<T> a);
};
template <class T> A<T> foo(A<T> a) { return a; }
int main()
{
A<int> a;
A<int> b = foo(a);
return 0;
}
---------------------------------------
/usr/local/bin/g++ tmp.cc
tmp.cc:3: warning: friend declaration `class A<T> foo(class A<T>)'
tmp.cc:3: warning: will not be treated as a template instantiation
tmp.cc:3: warning: unless you compile with -fguiding-decls
tmp.cc:3: warning: or add <> after the function name
/tmp/cca007971.o: In function `main':
/tmp/cca007971.o(.text+0x19): undefined reference to `foo(A<int>)'
collect2: ld returned 1 exit status
Notice what it says, about adding <> after the function name. If I
just change the friend declaration to
friend A<T> foo<> (A<T> a);
I get a syntax error like I'd expect. Then I tried changing it to
friend A<T> foo<T> (A<T> a);
at which point I got an internal compiler error. I figured that
regardless of whether it was a syntax error, the compiler shouldn't
crash, so I sent a bug report. If I add the declarations that
Alexandre suggested:
template <class T> class A;
template <class T> A<T> foo(A<T>);
before the class declaration, I still get the same warning, and link
error.
--------------- tmp.cc ---------------
template <class T> class A;
template <class T> A<T> foo(A<T>);
template <class T>
class A {
public:
friend A<T> foo(A<T> a);
};
template <class T> A<T> foo(A<T> a) { return a; }
int main()
{
A<int> a;
A<int> b = foo(a);
return 0;
}
---------------------------------------
/usr/local/bin/g++ tmp.cc
tmp.cc:6: warning: friend declaration `class A<T> foo(class A<T>)'
tmp.cc:6: warning: will not be treated as a template instantiation
tmp.cc:6: warning: unless you compile with -fguiding-decls
tmp.cc:6: warning: or add <> after the function name
/tmp/cca008151.o: In function `main':
/tmp/cca008151.o(.text+0x19): undefined reference to `foo(A<int>)'
collect2: ld returned 1 exit status
Finally, if I change the call to foo, in main, to foo<int>(a);, then
it compiles, though I still get the warning message. I guess this is
what the warning message was saying to do, but in that case, I think
the warning message should be changed to
"... or add <> after the function name when calling the function"
so that it's clear that it's not saying to add <> after the function
name in the friend declaration, which is where the warning is.
Adam
More information about the Gcc-bugs
mailing list