* [Bug c++/30822] wrong choice of overloaded template functions in recursive call
2007-02-16 12:09 [Bug c++/30822] New: wrong choice of overloaded template functions in recursive call Zarathustra at gentlemansclub dot de
@ 2007-02-16 15:47 ` pinskia at gcc dot gnu dot org
2007-02-16 16:35 ` Zarathustra at gentlemansclub dot de
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-02-16 15:47 UTC (permalink / raw)
To: gcc-bugs
------- Comment #1 from pinskia at gcc dot gnu dot org 2007-02-16 15:47 -------
// now the order changed and the compiler complains!
I think GCC 4.1.x and above are doing the correct behavior with respect of the
C++ standard. The C++ standard has specific rules about namelookup in
templates which differs from what most people think they are as before GCC
4.1.x did not implement them and I think Microsoft's VS also still does not
implement them.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/30822] wrong choice of overloaded template functions in recursive call
2007-02-16 12:09 [Bug c++/30822] New: wrong choice of overloaded template functions in recursive call Zarathustra at gentlemansclub dot de
2007-02-16 15:47 ` [Bug c++/30822] " pinskia at gcc dot gnu dot org
@ 2007-02-16 16:35 ` Zarathustra at gentlemansclub dot de
2007-02-21 7:44 ` Zarathustra at gentlemansclub dot de
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Zarathustra at gentlemansclub dot de @ 2007-02-16 16:35 UTC (permalink / raw)
To: gcc-bugs
------- Comment #2 from Zarathustra at gentlemansclub dot de 2007-02-16 16:35 -------
I know the rules for template function name lookup are complicated, and I do
not claim that I understand them completely. But I am pretty sure that the
order of the definitions should not matter. There is a partial ordering of
template functions to decide which function is used. This ordering depends on
which function is "more specialized" than the other, but not the sequence of
the definitions.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/30822] wrong choice of overloaded template functions in recursive call
2007-02-16 12:09 [Bug c++/30822] New: wrong choice of overloaded template functions in recursive call Zarathustra at gentlemansclub dot de
2007-02-16 15:47 ` [Bug c++/30822] " pinskia at gcc dot gnu dot org
2007-02-16 16:35 ` Zarathustra at gentlemansclub dot de
@ 2007-02-21 7:44 ` Zarathustra at gentlemansclub dot de
2007-02-21 10:16 ` Zarathustra at gentlemansclub dot de
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Zarathustra at gentlemansclub dot de @ 2007-02-21 7:44 UTC (permalink / raw)
To: gcc-bugs
------- Comment #3 from Zarathustra at gentlemansclub dot de 2007-02-21 07:44 -------
The same problem appears with gcc 4.1.2 20061115 (prerelease) (SUSE Linux)
--
Zarathustra at gentlemansclub dot de changed:
What |Removed |Added
----------------------------------------------------------------------------
Version|4.1.1 |4.1.2
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/30822] wrong choice of overloaded template functions in recursive call
2007-02-16 12:09 [Bug c++/30822] New: wrong choice of overloaded template functions in recursive call Zarathustra at gentlemansclub dot de
` (2 preceding siblings ...)
2007-02-21 7:44 ` Zarathustra at gentlemansclub dot de
@ 2007-02-21 10:16 ` Zarathustra at gentlemansclub dot de
2007-03-09 4:14 ` bangerth at dealii dot org
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Zarathustra at gentlemansclub dot de @ 2007-02-21 10:16 UTC (permalink / raw)
To: gcc-bugs
------- Comment #4 from Zarathustra at gentlemansclub dot de 2007-02-21 10:16 -------
Now the code was also compiled with 4.3.0 and produced the same error message.
I can make the actual failure more specific: The following code compiles fine:
template<template<typename> class TOperator,typename TElement>
void for_all_5(TElement elem, cons_end tail);
template<template<typename> class TOperator,typename TElement, typename TTail>
void for_all_5(TElement elem, TTail tail)
{
TOperator<TElement>()(elem);
for_all_5<TOperator>(tail.elem,tail.tail);
}
template<template<typename> class TOperator,typename TElement>
void for_all_5(TElement elem, cons_end tail)
{
TOperator<TElement>()(elem);
}
// -- snip -- //
in main:
for_all_5<op>(list.elem,list.tail);
The difference is the forward declaration of the second for_all method.
>From my understanding of the standard it is not necessary to do the forward
declaration since by 14.6.4/1 declarations which are visible at the point of
instantiation are to be considered and by 14.6.4.1/1 the point of
instantiation of all template functions is at the definition of the main
function.
--
Zarathustra at gentlemansclub dot de changed:
What |Removed |Added
----------------------------------------------------------------------------
Version|4.1.2 |4.3.0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/30822] wrong choice of overloaded template functions in recursive call
2007-02-16 12:09 [Bug c++/30822] New: wrong choice of overloaded template functions in recursive call Zarathustra at gentlemansclub dot de
` (3 preceding siblings ...)
2007-02-21 10:16 ` Zarathustra at gentlemansclub dot de
@ 2007-03-09 4:14 ` bangerth at dealii dot org
2007-03-09 12:36 ` Zarathustra at gentlemansclub dot de
2007-05-17 12:27 ` Zarathustra at gentlemansclub dot de
6 siblings, 0 replies; 8+ messages in thread
From: bangerth at dealii dot org @ 2007-03-09 4:14 UTC (permalink / raw)
To: gcc-bugs
------- Comment #5 from bangerth at dealii dot org 2007-03-09 04:14 -------
Here's a reduced code:
-----------------
struct cons_end {};
template<typename U,typename V> struct cons {
U elem;
V tail;
};
template<class T,typename U, typename V>
void foo(U elem, V tail)
{
foo<T>(tail.elem,tail.tail);
}
template<class T,typename U>
void foo(U elem, cons_end tail)
{}
int main()
{
cons<int,cons<int,cons_end> > list;
foo<int>(list.elem,list.tail);
}
--------------------
With gcc3.3, we get this error:
tmp/g> c++ -c x.cc
x.cc: In function `void foo(U, V) [with T = int, U = int, V = cons<int,
cons_end>]':
x.cc:21: instantiated from here
x.cc:11: error: call of overloaded `foo(int&, cons_end&)' is ambiguous
x.cc:10: error: candidates are: void foo(U, V) [with T = int, U = int, V =
cons_end]
x.cc:16: error: void foo(U, cons_end) [with T = int, U = int]
On the other hand, gcc 4.1 produces this:
g/x> c++ -c x.cc
x.cc: In function 'void foo(U, V) [with T = int, U = int, V = cons_end]':
x.cc:11: instantiated from 'void foo(U, V) [with T = int, U = int, V =
cons<int, cons_end>]'
x.cc:21: instantiated from here
x.cc:11: error: 'struct cons_end' has no member named 'elem'
x.cc:11: error: 'struct cons_end' has no member named 'tail'
Finally, icc gives me this:
tmp/g> icc -c x.cc
x.cc(21): warning #592: variable "list" is used before its value is set
foo<int>(list.elem,list.tail);
^
x.cc(11): error: more than one instance of overloaded function "foo" matches
the argument list:
function template "foo<T,U,V>(U, V)"
function template "foo<T,U>(U, cons_end)"
argument types are: (int, cons_end)
foo<T>(tail.elem,tail.tail);
^
detected during instantiation of "void foo<T,U,V>(U, V) [with T=int,
U=int, V=cons<int, cons_end>]"
compilation aborted for x.cc (code 2)
So, the way I read this is that gcc3.3 and icc9.0 agree that the call is
ambiguous. I must admit that I don't know whether this is the correct
behavior.
On the other hand, gcc4.1 appears to not find an ambiguity, then goes on to
unconditionally call the first function and there hits onto a problem.
W.
--
bangerth at dealii dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |bangerth at dealii dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/30822] wrong choice of overloaded template functions in recursive call
2007-02-16 12:09 [Bug c++/30822] New: wrong choice of overloaded template functions in recursive call Zarathustra at gentlemansclub dot de
` (4 preceding siblings ...)
2007-03-09 4:14 ` bangerth at dealii dot org
@ 2007-03-09 12:36 ` Zarathustra at gentlemansclub dot de
2007-05-17 12:27 ` Zarathustra at gentlemansclub dot de
6 siblings, 0 replies; 8+ messages in thread
From: Zarathustra at gentlemansclub dot de @ 2007-03-09 12:36 UTC (permalink / raw)
To: gcc-bugs
------- Comment #6 from Zarathustra at gentlemansclub dot de 2007-03-09 12:35 -------
(In reply to comment #5)
> So, the way I read this is that gcc3.3 and icc9.0 agree that the call is
> ambiguous. I must admit that I don't know whether this is the correct
> behavior.
Also the SunCC yields the ambiguity message. I think in all such cases the
compilers do not implement all rules for the look up of template names as given
by the standard. Probably starting from version 3.4.0 of gcc the error message
changes.
Perhaps it is worth taking a look at the following code:
One template argument is left away, and some "<>" are added.
foo2 is accepted, foo3 is not! From this I assume that there is some problem
with the implementation of the argument-dependent lookup (ADP) in gcc. Does
anyone have any other assumptions?
struct cons_end {};
template<typename U,typename V> struct cons {
U elem;
V tail;
};
template<typename U, typename V>
void foo2(U elem, V tail)
{
foo2(tail.elem,tail.tail);
}
template<typename U>
void foo2(U elem, cons_end tail)
{}
template<typename U, typename V>
void foo3(U elem, V tail)
{
foo3<>(tail.elem,tail.tail); // <-- the difference is here (<> added)
}
template<typename U>
void foo3(U elem, cons_end tail)
{}
int main()
{
cons<int,cons<int,cons_end> > list;
foo2(list.elem,list.tail);
foo2<>(list.elem,list.tail);
foo3(list.elem,list.tail);
}
The error message (from gcc 4.1.2 and gcc 4.3):
test_gccbug.cpp: In function "void foo3(U, V) [with U = int, V = cons_end]":
test_gccbug.cpp:32: instantiated from "void foo3(U, V) [with U = int, V =
cons<int, cons_end>]"
test_gccbug.cpp:44: instantiated from here
test_gccbug.cpp:32: error: "struct cons_end" has no member named "elem"
test_gccbug.cpp:32: error: "struct cons_end" has no member named "tail"
Volker
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/30822] wrong choice of overloaded template functions in recursive call
2007-02-16 12:09 [Bug c++/30822] New: wrong choice of overloaded template functions in recursive call Zarathustra at gentlemansclub dot de
` (5 preceding siblings ...)
2007-03-09 12:36 ` Zarathustra at gentlemansclub dot de
@ 2007-05-17 12:27 ` Zarathustra at gentlemansclub dot de
6 siblings, 0 replies; 8+ messages in thread
From: Zarathustra at gentlemansclub dot de @ 2007-05-17 12:27 UTC (permalink / raw)
To: gcc-bugs
------- Comment #7 from Zarathustra at gentlemansclub dot de 2007-05-17 13:27 -------
According to my current understanding, the compiler is right not to accept the
given example code:
Name resolution at the point of instantiation does only work for dependent
names.
Given a expression which looks like
"postfix-expression ( expression-listopt )"
"postfix-expression" is a dependent name if (and only if) some thing in
"expression-listopt" depends on a template parameter and "postfix-expression"
is an identifier. This holds for foo(...) but it does not hold for
foo<...>(...) or ::foo(...). Therefore I assume the compiler behaves
correctly. This is probably another case where the C++ standard is somehow
counterintuitive.
--
Zarathustra at gentlemansclub dot de changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |INVALID
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30822
^ permalink raw reply [flat|nested] 8+ messages in thread