public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* RE: Possible gcc 3.4/4.0 bug wrt template dependant lookup
@ 2004-11-16 17:47 Pollard, Andrew
  0 siblings, 0 replies; 5+ messages in thread
From: Pollard, Andrew @ 2004-11-16 17:47 UTC (permalink / raw)
  To: gcc


Please ignore this mail, I'm having trouble with my mail system at work, and this message is truncated. I'll attempt to send the correct version...

Andrew.

-----Original Message-----
From: Pollard, Andrew 
Sent: 16 November 2004 17:36
To: 'gcc@gcc.gnu.org'
Cc: Pollard, Andrew
Subject: Possible gcc 3.4/4.0 bug wrt template dependant lookup

The program in question is
 
foo.cxx:
------------------------------------
template<typename T> int foo(const T&)      { return (1);          }
template<typename T> struct M { int bar()   { return (::foo(T())); } };
template<typename T> struct S { int bar()   { return (T(0));       } };
template<typename T> int foo(const S<T>& s) { return (s.bar());    }
 
int
main()
{
    M<S<int> > q;
    return (q.bar());
}
------------------------------------
 
% g++34 foo.cxx; ./a.out; echo $?
1
% g++40 foo.cxx; ./a.out; echo $?
1
% g++33 foo.cxx; ./a.out; echo $?
0
 
If I change line 2 to be
 
template<typename T> struct M { int bar()   { return (foo(T())); } };
 
ie, remove the :: qualification on foo, it returns 0.
 
Also, if I move the 'struct M' to after the foo() specialization for S<T>,
it also returns 0 (with or without the :: qualification)
 
It is as if the :: qualification is stopping the bar() method being template
type dependent, and binding the call at parse time and not at instantiation
time (in this case, getting the base template for foo() and not the specialization)
 
What, if anything, am I missing?
 
Thanks,
 Andrew.

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

* Re: Possible gcc 3.4/4.0 bug wrt template dependant lookup
  2004-11-16 17:51 Pollard, Andrew
@ 2004-11-16 18:24 ` Nathan Sidwell
  0 siblings, 0 replies; 5+ messages in thread
From: Nathan Sidwell @ 2004-11-16 18:24 UTC (permalink / raw)
  To: Pollard, Andrew; +Cc: gcc

Pollard, Andrew wrote:
> Hi all,
> 
> [ Using gcc-3.4.4-20041116 and gcc-4.0.0-20041116 ]
> 
> I don't know whether this is a gcc bug, or Standard mandated behaviour
> with
> the two stage dependant name lookup in templates. Can someone here
> clarify?
> 
> The program in question is
> 
> foo.cxx:
> ------------------------------------
> template<typename T> int foo(const T&)      { return (1);          }
> template<typename T> struct M { int bar()   { return (::foo(T())); } };
> template<typename T> struct S { int bar()   { return (T(0));       } };
> template<typename T> int foo(const S<T>& s) { return (s.bar());    }

to continue,
> template<typename T> struct M { int bar() { return (foo(T())); } };
> 
> ie, remove the :: qualification on foo, it returns 0.
yes, because now it is a dependent expression, fitting the syntax of
[14.6.2].  Thus lookup is done at instantiation time in both the
context of the definition AND of the instantiation.  Hence we find
both overloads of ::foo, deduce both successfully and find that the
second one is more specialized than the first.

> Also, if I move the 'struct M' to after the foo() specialization for
> S<T>,
> it also returns 0 (with or without the :: qualification)
Yes, because both overloads are visible at definition time, and bound
then (overload resolution itself occurs at instantiation time when T is
known).

> 
> It is as if the :: qualification is stopping the bar() method being
> template
> type dependent, and binding the call at parse time and not at
> instantiation
> time (in this case, getting the base template for foo() and not the
> specialization)
yes it is doing that, because that's what the std says :)

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: Possible gcc 3.4/4.0 bug wrt template dependant lookup
  2004-11-16 17:35 Pollard, Andrew
@ 2004-11-16 17:56 ` Nathan Sidwell
  0 siblings, 0 replies; 5+ messages in thread
From: Nathan Sidwell @ 2004-11-16 17:56 UTC (permalink / raw)
  To: Pollard, Andrew; +Cc: gcc

Pollard, Andrew wrote:
> The program in question is
>  
> foo.cxx:
> ------------------------------------
> template<typename T> int foo(const T&)      { return (1);          }
> template<typename T> struct M { int bar()   { return (::foo(T())); } };
> template<typename T> struct S { int bar()   { return (T(0));       } };
> template<typename T> int foo(const S<T>& s) { return (s.bar());    }
>  

> It is as if the :: qualification is stopping the bar() method being template
> type dependent, and binding the call at parse time and not at instantiation
> time (in this case, getting the base template for foo() and not the specialization)

correct. ::foo is bound at parse time to those foo's visible at the point
of definition.  That's ::foo(const T&).  This gets instantiated when M<T>::bar
gets instantiated.  The other ::foo, ::foo(const S<T>&) is a different overload,
(it's not a partial specialization, 'cos there are no such things as function
partial specializations).

[14.6] has the details

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Possible gcc 3.4/4.0 bug wrt template dependant lookup
@ 2004-11-16 17:51 Pollard, Andrew
  2004-11-16 18:24 ` Nathan Sidwell
  0 siblings, 1 reply; 5+ messages in thread
From: Pollard, Andrew @ 2004-11-16 17:51 UTC (permalink / raw)
  To: gcc; +Cc: Pollard, Andrew


Hi all,

[ Using gcc-3.4.4-20041116 and gcc-4.0.0-20041116 ]

I don't know whether this is a gcc bug, or Standard mandated behaviour
with
the two stage dependant name lookup in templates. Can someone here
clarify?

The program in question is

foo.cxx:
------------------------------------
template<typename T> int foo(const T&)      { return (1);          }
template<typename T> struct M { int bar()   { return (::foo(T())); } };
template<typename T> struct S { int bar()   { return (T(0));       } };
template<typename T> int foo(const S<T>& s) { return (s.bar());    }

int
main()
{
    M<S<int> > q;
    return (q.bar());
}
------------------------------------

% g++34 foo.cxx; ./a.out; echo $?
1
% g++40 foo.cxx; ./a.out; echo $?
1
% g++33 foo.cxx; ./a.out; echo $?
0

If I change line 2 to be

template<typename T> struct M { int bar() { return (foo(T())); } };

ie, remove the :: qualification on foo, it returns 0.

Also, if I move the 'struct M' to after the foo() specialization for
S<T>,
it also returns 0 (with or without the :: qualification)

It is as if the :: qualification is stopping the bar() method being
template
type dependent, and binding the call at parse time and not at
instantiation
time (in this case, getting the base template for foo() and not the
specialization)

What, if anything, am I missing?

Thanks,
 Andrew.
-- 
   Andrew Pollard - Senior Software Engineer
Brooks Automation - Software Systems Group (APF)
 Andrew.Pollard@brooks.com : +44 (0)118 9215603

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

* Possible gcc 3.4/4.0 bug wrt template dependant lookup
@ 2004-11-16 17:35 Pollard, Andrew
  2004-11-16 17:56 ` Nathan Sidwell
  0 siblings, 1 reply; 5+ messages in thread
From: Pollard, Andrew @ 2004-11-16 17:35 UTC (permalink / raw)
  To: gcc; +Cc: Pollard, Andrew

The program in question is
 
foo.cxx:
------------------------------------
template<typename T> int foo(const T&)      { return (1);          }
template<typename T> struct M { int bar()   { return (::foo(T())); } };
template<typename T> struct S { int bar()   { return (T(0));       } };
template<typename T> int foo(const S<T>& s) { return (s.bar());    }
 
int
main()
{
    M<S<int> > q;
    return (q.bar());
}
------------------------------------
 
% g++34 foo.cxx; ./a.out; echo $?
1
% g++40 foo.cxx; ./a.out; echo $?
1
% g++33 foo.cxx; ./a.out; echo $?
0
 
If I change line 2 to be
 
template<typename T> struct M { int bar()   { return (foo(T())); } };
 
ie, remove the :: qualification on foo, it returns 0.
 
Also, if I move the 'struct M' to after the foo() specialization for S<T>,
it also returns 0 (with or without the :: qualification)
 
It is as if the :: qualification is stopping the bar() method being template
type dependent, and binding the call at parse time and not at instantiation
time (in this case, getting the base template for foo() and not the specialization)
 
What, if anything, am I missing?
 
Thanks,
 Andrew.

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

end of thread, other threads:[~2004-11-16 17:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-16 17:47 Possible gcc 3.4/4.0 bug wrt template dependant lookup Pollard, Andrew
  -- strict thread matches above, loose matches on Subject: below --
2004-11-16 17:51 Pollard, Andrew
2004-11-16 18:24 ` Nathan Sidwell
2004-11-16 17:35 Pollard, Andrew
2004-11-16 17:56 ` Nathan Sidwell

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).