public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* A simple sample code involving templates, friends and lookup
@ 2008-01-17 11:08 Dragan Milenkovic
  2008-01-17 12:56 ` Richard Guenther
  0 siblings, 1 reply; 13+ messages in thread
From: Dragan Milenkovic @ 2008-01-17 11:08 UTC (permalink / raw)
  To: gcc

Hello,

I'm aware about these issues being around for quite a while now, but
there is still a chance this sample code can be helpful. I apologize
if someone gets annoyed :-P


template <typename T>
struct Foo
{
     template <typename Z>
     friend void func(const Foo &);
};

void check(const Foo<int> & x)
{
     // Foo<int> weird;  // uncomment this line and all works

     func<int>(x);    // <-- ERROR
}


Tested with gcc 4.0 - 4.3, and all behave the same:

"error: ‘func’ was not declared in this scope"

but it works if you uncomment the weird line.


Best regards,

Dragan Milenkovic

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 11:08 A simple sample code involving templates, friends and lookup Dragan Milenkovic
@ 2008-01-17 12:56 ` Richard Guenther
  2008-01-17 13:24   ` Dragan Milenkovic
  2008-01-17 13:35   ` Paolo Bonzini
  0 siblings, 2 replies; 13+ messages in thread
From: Richard Guenther @ 2008-01-17 12:56 UTC (permalink / raw)
  To: Dragan Milenkovic; +Cc: gcc

On Jan 17, 2008 11:44 AM, Dragan Milenkovic <dragan@plusplus.co.yu> wrote:
> Hello,
>
> I'm aware about these issues being around for quite a while now, but
> there is still a chance this sample code can be helpful. I apologize
> if someone gets annoyed :-P
>
>
> template <typename T>
> struct Foo
> {
>      template <typename Z>
>      friend void func(const Foo &);
> };
>
> void check(const Foo<int> & x)
> {
>      // Foo<int> weird;  // uncomment this line and all works
>
>      func<int>(x);    // <-- ERROR
> }
>
>
> Tested with gcc 4.0 - 4.3, and all behave the same:
>
> "error: 'func' was not declared in this scope"
>
> but it works if you uncomment the weird line.

Actually even with the weird line the program is invalid.  What are
you trying to do? ;)

Richard.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 12:56 ` Richard Guenther
@ 2008-01-17 13:24   ` Dragan Milenkovic
  2008-01-17 14:46     ` Richard Guenther
  2008-01-17 13:35   ` Paolo Bonzini
  1 sibling, 1 reply; 13+ messages in thread
From: Dragan Milenkovic @ 2008-01-17 13:24 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc

Richard Guenther wrote:
[snip]
>> template <typename T>
>> struct Foo
>> {
>>      template <typename Z>
>>      friend void func(const Foo &);
>> };
>>
>> void check(const Foo<int> & x)
>> {
>>      // Foo<int> weird;  // uncomment this line and all works
>>
>>      func<int>(x);    // <-- ERROR
>> }
>>
>>
>> Tested with gcc 4.0 - 4.3, and all behave the same:
>>
>> "error: 'func' was not declared in this scope"
>>
>> but it works if you uncomment the weird line.
> 
> Actually even with the weird line the program is invalid.  What are
> you trying to do? ;)
> 
> Richard.

Ok... afaik, that func should be defined on that very place where it is
declared as friend. But could you please elaborate why it is invalid,
since you made me start questioning my C++ knowledge... :-D

Dragan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 12:56 ` Richard Guenther
  2008-01-17 13:24   ` Dragan Milenkovic
@ 2008-01-17 13:35   ` Paolo Bonzini
  1 sibling, 0 replies; 13+ messages in thread
From: Paolo Bonzini @ 2008-01-17 13:35 UTC (permalink / raw)
  To: gcc


>> template <typename T>
>> struct Foo
>> {
>>      template <typename Z>
>>      friend void func(const Foo &);
>> };
>>
>> void check(const Foo<int> & x)
>> {
>>      // Foo<int> weird;  // uncomment this line and all works
>>
>>      func<int>(x);    // <-- ERROR
>> }
>>
>>
>> Tested with gcc 4.0 - 4.3, and all behave the same:
>>
>> "error: 'func' was not declared in this scope"
>>
>> but it works if you uncomment the weird line.
> 
> Actually even with the weird line the program is invalid.  What are
> you trying to do? ;)

I don't know if it is invalid or not, but with the weird line 
uncommented it compiles (like if func was brought into scope).

Paolo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 13:24   ` Dragan Milenkovic
@ 2008-01-17 14:46     ` Richard Guenther
  2008-01-17 17:12       ` Ian Lance Taylor
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Guenther @ 2008-01-17 14:46 UTC (permalink / raw)
  To: Dragan Milenkovic; +Cc: gcc

On Jan 17, 2008 2:12 PM, Dragan Milenkovic <dragan@plusplus.co.yu> wrote:
> Richard Guenther wrote:
> [snip]
> >> template <typename T>
> >> struct Foo
> >> {
> >>      template <typename Z>
> >>      friend void func(const Foo &);
> >> };
> >>
> >> void check(const Foo<int> & x)
> >> {
> >>      // Foo<int> weird;  // uncomment this line and all works
> >>
> >>      func<int>(x);    // <-- ERROR
> >> }
> >>
> >>
> >> Tested with gcc 4.0 - 4.3, and all behave the same:
> >>
> >> "error: 'func' was not declared in this scope"
> >>
> >> but it works if you uncomment the weird line.
> >
> > Actually even with the weird line the program is invalid.  What are
> > you trying to do? ;)
> >
> > Richard.
>
> Ok... afaik, that func should be defined on that very place where it is
> declared as friend. But could you please elaborate why it is invalid,
> since you made me start questioning my C++ knowledge... :-D

How should name-lookup find func?

Richard.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 14:46     ` Richard Guenther
@ 2008-01-17 17:12       ` Ian Lance Taylor
  2008-01-17 18:09         ` Richard Guenther
  0 siblings, 1 reply; 13+ messages in thread
From: Ian Lance Taylor @ 2008-01-17 17:12 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Dragan Milenkovic, gcc

"Richard Guenther" <richard.guenther@gmail.com> writes:

> On Jan 17, 2008 2:12 PM, Dragan Milenkovic <dragan@plusplus.co.yu> wrote:
> > Richard Guenther wrote:
> > [snip]
> > >> template <typename T>
> > >> struct Foo
> > >> {
> > >>      template <typename Z>
> > >>      friend void func(const Foo &);
> > >> };
> > >>
> > >> void check(const Foo<int> & x)
> > >> {
> > >>      // Foo<int> weird;  // uncomment this line and all works
> > >>
> > >>      func<int>(x);    // <-- ERROR
> > >> }
> > >>
> > >>
> > >> Tested with gcc 4.0 - 4.3, and all behave the same:
> > >>
> > >> "error: 'func' was not declared in this scope"
> > >>
> > >> but it works if you uncomment the weird line.
> > >
> > > Actually even with the weird line the program is invalid.  What are
> > > you trying to do? ;)
> > >
> > > Richard.
> >
> > Ok... afaik, that func should be defined on that very place where it is
> > declared as friend. But could you please elaborate why it is invalid,
> > since you made me start questioning my C++ knowledge... :-D
> 
> How should name-lookup find func?

It should use argument dependent lookup.  This is like the common case
of

class x
{
  friend x operator+(const& x, const& x) { return x.var + x.var; }
};

in which x::operator+ is found without taking special action.

Ian

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 17:12       ` Ian Lance Taylor
@ 2008-01-17 18:09         ` Richard Guenther
  2008-01-17 22:23           ` Ian Lance Taylor
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Guenther @ 2008-01-17 18:09 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Dragan Milenkovic, gcc

On 17 Jan 2008 09:09:38 -0800, Ian Lance Taylor <iant@google.com> wrote:
>
> "Richard Guenther" <richard.guenther@gmail.com> writes:
>
> > On Jan 17, 2008 2:12 PM, Dragan Milenkovic <dragan@plusplus.co.yu> wrote:
> > > Richard Guenther wrote:
> > > [snip]
> > > >> template <typename T>
> > > >> struct Foo
> > > >> {
> > > >>      template <typename Z>
> > > >>      friend void func(const Foo &);
> > > >> };
> > > >>
> > > >> void check(const Foo<int> & x)
> > > >> {
> > > >>      // Foo<int> weird;  // uncomment this line and all works
> > > >>
> > > >>      func<int>(x);    // <-- ERROR
> > > >> }
> > > >>
> > > >>
> > > >> Tested with gcc 4.0 - 4.3, and all behave the same:
> > > >>
> > > >> "error: 'func' was not declared in this scope"
> > > >>
> > > >> but it works if you uncomment the weird line.
> > > >
> > > > Actually even with the weird line the program is invalid.  What are
> > > > you trying to do? ;)
> > > >
> > > > Richard.
> > >
> > > Ok... afaik, that func should be defined on that very place where it is
> > > declared as friend. But could you please elaborate why it is invalid,
> > > since you made me start questioning my C++ knowledge... :-D
> >
> > How should name-lookup find func?
>
> It should use argument dependent lookup.  This is like the common case
> of
>
> class x
> {
>   friend x operator+(const& x, const& x) { return x.var + x.var; }
> };
>
> in which x::operator+ is found without taking special action.

Well, first I think you'd need friend-injection or otherwise a global
decl of the function.  Second I thought argument dependent
name-lookup only applies to namespaces, not classes.

EDG rejects this consistently btw.

Richard.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 18:09         ` Richard Guenther
@ 2008-01-17 22:23           ` Ian Lance Taylor
  2008-01-17 22:59             ` Richard Guenther
  0 siblings, 1 reply; 13+ messages in thread
From: Ian Lance Taylor @ 2008-01-17 22:23 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Dragan Milenkovic, gcc

"Richard Guenther" <richard.guenther@gmail.com> writes:

> > > On Jan 17, 2008 2:12 PM, Dragan Milenkovic <dragan@plusplus.co.yu> wrote:
> > > > Richard Guenther wrote:
> > > > [snip]
> > > > >> template <typename T>
> > > > >> struct Foo
> > > > >> {
> > > > >>      template <typename Z>
> > > > >>      friend void func(const Foo &);
> > > > >> };
> > > > >>
> > > > >> void check(const Foo<int> & x)
> > > > >> {
> > > > >>      // Foo<int> weird;  // uncomment this line and all works
> > > > >>
> > > > >>      func<int>(x);    // <-- ERROR
> > > > >> }
> > > > >>
> > > > >>
> > > > >> Tested with gcc 4.0 - 4.3, and all behave the same:
> > > > >>
> > > > >> "error: 'func' was not declared in this scope"
> > > > >>
> > > > >> but it works if you uncomment the weird line.
> > > > >
> > > > > Actually even with the weird line the program is invalid.  What are
> > > > > you trying to do? ;)
> > > > >
> > > > > Richard.
> > > >
> > > > Ok... afaik, that func should be defined on that very place where it is
> > > > declared as friend. But could you please elaborate why it is invalid,
> > > > since you made me start questioning my C++ knowledge... :-D
> > >
> > > How should name-lookup find func?
> >
> > It should use argument dependent lookup.  This is like the common case
> > of
> >
> > class x
> > {
> >   friend x operator+(const& x, const& x) { return x.var + x.var; }
> > };
> >
> > in which x::operator+ is found without taking special action.
> 
> Well, first I think you'd need friend-injection or otherwise a global
> decl of the function.

ADL works without friend injection.  Look at 3.4.2
[basic.lookup.koenig] in C++98.

> Second I thought argument dependent
> name-lookup only applies to namespaces, not classes.

No.

> EDG rejects this consistently btw.

Well, I'm probably misinterpreting the example.  Adding the templates
must change it somehow.

For example, this works fine, even without -ffriend-injection:

class x { friend x operator+(const x& x1, const x& x2); };
x foo(x x1, x x2) { return x1 + x2; }

Ian

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 22:23           ` Ian Lance Taylor
@ 2008-01-17 22:59             ` Richard Guenther
  2008-01-18  7:10               ` Jonathan Wakely
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Guenther @ 2008-01-17 22:59 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Dragan Milenkovic, gcc

On 17 Jan 2008 11:46:52 -0800, Ian Lance Taylor <iant@google.com> wrote:
>
> "Richard Guenther" <richard.guenther@gmail.com> writes:
> >
> > Well, first I think you'd need friend-injection or otherwise a global
> > decl of the function.
>
> ADL works without friend injection.  Look at 3.4.2
> [basic.lookup.koenig] in C++98.

I did.  It says "other _namespaces_ not considered...".

> > Second I thought argument dependent
> > name-lookup only applies to namespaces, not classes.
>
> No.
>
> > EDG rejects this consistently btw.
>
> Well, I'm probably misinterpreting the example.  Adding the templates
> must change it somehow.

Well, the actual call to func is not dependent, so it should not affect
name-resolution.

> For example, this works fine, even without -ffriend-injection:
>
> class x { friend x operator+(const x& x1, const x& x2); };
> x foo(x x1, x x2) { return x1 + x2; }

It does, even with EDG.

Well, a language lawyer can probably clear things up.  From a look
at the std it looks like w/o a previous declaration the above should
be invalid.  And at a different point it suggests the decl becomes
available.

Bah.

Richard.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-17 22:59             ` Richard Guenther
@ 2008-01-18  7:10               ` Jonathan Wakely
  2008-01-18  7:35                 ` Jonathan Wakely
  2008-01-18 14:17                 ` Dragan Milenkovic
  0 siblings, 2 replies; 13+ messages in thread
From: Jonathan Wakely @ 2008-01-18  7:10 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Ian Lance Taylor, Dragan Milenkovic, gcc

On 17/01/2008, Richard Guenther wrote:
>
> Well, a language lawyer can probably clear things up.  From a look
> at the std it looks like w/o a previous declaration the above should
> be invalid.  And at a different point it suggests the decl becomes
> available.

Yes, at the point of instantiation of Foo<int> the friend is declared,
and can then be found by ADL because Foo<int> is an associated type.
The reference parameter 'x' doesn't cause an instantiation, only 'weird' does.

However, see the discussion in section 9.2.2 of Vandevoorde and
Josuttis' C++ Templates book and the footnote saying the standard
isn't exactly clear.

I'm only guessing, but EDG's behaviour could be related to their
interpretation of  DR329
http://www.open-std.org/jtc1/sc22/wg21//docs/cwg_defects.html#329

I'm not sure which interpretation is correct, but GCC's seems reasonable to me.

Jon

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-18  7:10               ` Jonathan Wakely
@ 2008-01-18  7:35                 ` Jonathan Wakely
  2008-01-18 14:17                 ` Dragan Milenkovic
  1 sibling, 0 replies; 13+ messages in thread
From: Jonathan Wakely @ 2008-01-18  7:35 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Ian Lance Taylor, Dragan Milenkovic, gcc

On 18/01/2008, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>
> Yes, at the point of instantiation of Foo<int> the friend is declared,
> and can then be found by ADL because Foo<int> is an associated type.
> The reference parameter 'x' doesn't cause an instantiation, only 'weird' does.

Forgot the reference - this is 14.6.5 [temp.inject]

DR387 fixes some errors in the example, but doesn't change the wording.
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#387

Jon

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-18  7:10               ` Jonathan Wakely
  2008-01-18  7:35                 ` Jonathan Wakely
@ 2008-01-18 14:17                 ` Dragan Milenkovic
  2008-01-19  8:21                   ` Jonathan Wakely
  1 sibling, 1 reply; 13+ messages in thread
From: Dragan Milenkovic @ 2008-01-18 14:17 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc

Jonathan Wakely wrote:
> On 17/01/2008, Richard Guenther wrote:
>> Well, a language lawyer can probably clear things up.  From a look
>> at the std it looks like w/o a previous declaration the above should
>> be invalid.  And at a different point it suggests the decl becomes
>> available.
> 
> Yes, at the point of instantiation of Foo<int> the friend is declared,
> and can then be found by ADL because Foo<int> is an associated type.
> The reference parameter 'x' doesn't cause an instantiation, only 'weird' does.
> 
> However, see the discussion in section 9.2.2 of Vandevoorde and
> Josuttis' C++ Templates book and the footnote saying the standard
> isn't exactly clear.
[snip]

Thanks for clarification and info. I believe issue #34 addresses exactly
what we're talking about.

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#34

Hey... the current number of issues is kinda scary... :-O

Dragan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: A simple sample code involving templates, friends and lookup
  2008-01-18 14:17                 ` Dragan Milenkovic
@ 2008-01-19  8:21                   ` Jonathan Wakely
  0 siblings, 0 replies; 13+ messages in thread
From: Jonathan Wakely @ 2008-01-19  8:21 UTC (permalink / raw)
  To: Dragan Milenkovic; +Cc: gcc

On 18/01/2008, Dragan Milenkovic <dragan@plusplus.co.yu> wrote:
>
> Thanks for clarification and info. I believe issue #34 addresses exactly
> what we're talking about.
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#34

Aha, yes ... but strangely that seems to have been closed as
Not-A-Defect for a long time: the templates book is newer and says the
standard isn't clear.

If the standard does clearly say an instantiation is required, GCC
should accept the code even without "weird" being declared, because
the call should cause an instantiation, and declare "func"

I'm ignoring the fact that func is only declared in your example, not
defined - to call it there must be a definition between the
declaration and point of instantiation - but turning the friend
declaration into a definition doesn't change GCC's behaviour.

I wonder why EDG rejects it .

> Hey... the current number of issues is kinda scary... :-O

Everyone has issues, even C++  :)

Jon

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2008-01-18 21:13 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-17 11:08 A simple sample code involving templates, friends and lookup Dragan Milenkovic
2008-01-17 12:56 ` Richard Guenther
2008-01-17 13:24   ` Dragan Milenkovic
2008-01-17 14:46     ` Richard Guenther
2008-01-17 17:12       ` Ian Lance Taylor
2008-01-17 18:09         ` Richard Guenther
2008-01-17 22:23           ` Ian Lance Taylor
2008-01-17 22:59             ` Richard Guenther
2008-01-18  7:10               ` Jonathan Wakely
2008-01-18  7:35                 ` Jonathan Wakely
2008-01-18 14:17                 ` Dragan Milenkovic
2008-01-19  8:21                   ` Jonathan Wakely
2008-01-17 13:35   ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).