PR 764

Martin Sebor sebor@roguewave.com
Fri Nov 17 10:06:00 GMT 2000


Nathan Sidwell wrote:
> 
> Hi,
> this is about C++ bug 764. The attached test case (derived from
> Martin's second test case) produces the following diagnostics,
> 
> nathan@uha:21>./g++ -B ./ -c current/764-3.ii
> current/764-3.ii:4: warning: friend declaration `bool operator==(const
> S<T>&,
>    const S<T>&)' declares a non-template function
> current/764-3.ii:4: warning: (if this is not what you intended, make
> sure the
>    function template has already been declared and add <> after the
> function
>    name here) -Wno-non-template-friend disables this warning.
> current/764-3.ii: In function `void foo(S<int>*)':
> current/764-3.ii:12: no match for `S<int>& == S<int>&' operator
> current/764-3.ii: In function `void baz(S<float>*)':
> current/764-3.ii:16: no match for `S<float>& != S<float>&' operator
> current/764-3.ii:6: candidates are: bool operator!=(const S<int>&, const
> 
> There's clearly some kind of bug here, something about foo causes S<int>
> to be instantiated, but too late to find a match for operator==
> 
> I don't understand is why we issue a warning for the declaration
> of S<T>::operator==, but not for the definition of S<T>::operator!=.
> 
> The relevant bit of the std is 14.5.3, that lists what sort of thing a
> friend declaration is. In this case it's neither a template-id nor a
> qualified id, therefore the last choice is,
>         the name shall be an unqualified id that declares an ordinary
>         (non-template) function
> but here we've used the template type as parameters, so it's templatized
> on something. Shouldn't we issue an error here in both cases?

I don't believe there is an error in the derived testcase. The operators
are, as you said, ordinary functions. They just happen to be defined in
the body of the template which is allowed in 11.4, p5.

The fact that they take S<T> as an argument means that there is exactly
one ordinary function for each specialization of S<T> and that function
is a friend of the respective specialization (this is analogous to the
::process (task<T>*) function in the example in 14.5.3).

There's no other way to express such a relationship and there's nothing
that outlaws the syntax. The friend could be defined outside of the
template but since it's an ordinary function it would have to be defined
separately for each specialization of S<T>.

As for the warning, I believe that while it may be useful to novices it
shouldn't be issued unless explicitly requested (e.g., as a remark).
Even then I'm not sure it's the best idea for a compiler to give
"helpful" hints on how to "improve" one's code, especially if the code
is perfectly correct.

Regards
Martin

> 
> nathan
> 
> --
> Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery
> LLC
>          'But that's a lie.' - 'Yes it is. What's your point?'
> nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ :
> nathan@acm.org
> 
>   ------------------------------------------------------------------------
> 
>    764-3.iiName: 764-3.ii
>            Type: ASCII text file (text/plain)


More information about the Gcc-bugs mailing list