Bug 34886 - Strangeness of name lookup in template function
Summary: Strangeness of name lookup in template function
Status: RESOLVED DUPLICATE of bug 29131
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
: 34893 (view as bug list)
Depends on:
Reported: 2008-01-20 16:30 UTC by Roman Ovseevich
Modified: 2009-12-08 22:02 UTC (History)
5 users (show)

See Also:
Host: openSuse 10.3
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Roman Ovseevich 2008-01-20 16:30:59 UTC
On compiling that code:

--- begin code ---
class Y {};

void f(Y*) { } // line 3. If comment - all ok

template < typename T>
void sel(T* a) { f(a); } //line 6

void f(void*) {}

int main(int argc, char **argv)
	sel((void*)0); //line 12
--- end code ---

Àppears error:
../main.cpp: In function ‘void sel(T*) [with T = void]’:
../main.cpp:12:   instantiated from here
../main.cpp:6: error: invalid conversion from ‘void*’ to ‘Y*’
../main.cpp:6: error:   initializing argument 1 of ‘void f(Y*)’

If comment line 3, then work.
Also work, if line 3 move after line 6.

If functions f(Y*), f(void*) and sel(T*) placed in different header files, then arise dependency on order including headers.
Comment 1 Andrew Pinski 2008-01-20 21:55:23 UTC
GCC is correct here.  Well partly.  It should reject it no matter what.
Comment 2 Andrew Pinski 2008-01-20 22:30:28 UTC
*** Bug 34893 has been marked as a duplicate of this bug. ***
Comment 3 Roman Ovseevich 2008-01-21 14:43:16 UTC
This case is similar to the bug 31047 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31047).

There Andrew Pinski wrote (comment 4):
> says this is invalid code.
>For a function call that depends on a template parameter, if the function is an
>unqualified-id but not a template-id, the candiate functions are found using
>the usual lookup rules (3.4.1, 3.4.2) except that:
>Paraphasing since I don't want to type it all in
>* non argument dependent lookup (3.4.1: template definition context
>* argument dependent lookup (3.4.2):  template definition context and template
>instation context

This case is argument dependent lookup, therefore should used both contexts - definition and instantiation.
Point of instantiation "sel(T* a) with T = void" - after "void f(void*)" and before "int main()".
Thus should be visible both f(void*) and f(Y*), whether not so?
Why gcc does not see "void f (void *)"?
Comment 4 Jonathan Wakely 2009-12-08 21:58:24 UTC
In resolving dependent names, names from the following sources are considered:
— Declarations that are visible at the point of de&#64257;nition of the template.
— Declarations from namespaces associated with the types of the function arguments both from the instantiation context ( and from the de&#64257;nition context.

— If T is a fundamental type, its associated sets of namespaces and classes are both empty.
— If T is a pointer to U or an array of U, its associated namespaces and classes are those associated with U.

void* is a pointer to fundamental type so has no associated namespaces, so only the first source is considered, and only f(T*) is visible at the point of definition. This is invalid.
Comment 5 Andrew Pinski 2009-12-08 22:01:41 UTC
Actually ....
Comment 6 Andrew Pinski 2009-12-08 22:02:59 UTC
> void* is a pointer to fundamental type so has no associated namespaces

Well there is a still open defect report that says this might not be true :).

*** This bug has been marked as a duplicate of 29131 ***