public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace
@ 2007-11-12 15:21 adl at gnu dot org
2007-11-12 19:02 ` [Bug c++/34073] " pinskia at gcc dot gnu dot org
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: adl at gnu dot org @ 2007-11-12 15:21 UTC (permalink / raw)
To: gcc-bugs
Two files are appended at the end of this report: temp1.cc and temp2.cc.
temp1.cc is the only file that causes a problem with recent releases
of GCC. It contains :
1. a template definition of Structure<S>
2. a template definition of op_is_finite<S>(const Structure<S>*)
3. a template definition of algebra::AlphabetSet<L> inheriting from Structure
4. a template definition of Element<L>
that calls op_is_finite(const algebra::AlphabetSet<L>*) in its ctor
5. a template overloaded definition for
op_is_finite<L>(const algebra::AlphabetSet<L>*)
6. a main function that instantiate Element<char>.
Because all definitions but main() are template, I expect the call to
op_is_finite() in the ctor of Element<L> (#4) to be resolved during the
instantiation of Element<char> (#6) after the second definition
of op_is_finite() (#5) has been read. So the call would be bound
to that second definition and not to the first.
I have tested three GCC versions :
g++-3.4 (GCC) 3.4.6 (Debian 3.4.6-6)
g++-4.1 (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
g++-4.2 (GCC) 4.2.3 20071014 (prerelease) (Debian 4.2.2-3)
Both 4.1 and 4.2 behave identically: they seem to ignore the second
definition of op_is_finite and try to call the first.
3.4 does what we expect: it calls the second definition.
We have found at least two ways to alter temp1.cc such that 4.2 will
compile it.
- One is to move the second definition of op_is_finite() (#5) before its
use in the constructor of Element<L> (#4).
This ordering would make sense to me if the functions were not
template, but it's not clear why this would change anything in
the resolution of template overloaded functions. I might be
missing something.
- Another possibility is to move AlphabetSet<L> struct out of
the "algebra::" namespace. temp2.cc contains the updated
code.
I'm really surprized that 4.2 compiles temp2.cc
without problem and fails on temp1.cc.
//////////////////////////////////////////////////////
//////////////// temp1.cc starts here ////////////////
//////////////////////////////////////////////////////
template<typename S> struct Structure {};
template<typename S>
bool op_is_finite (const Structure<S>*)
{
// Error on purpose, this function is not expected to be instantiated.
return Structure<S>();
}
namespace algebra
{
template <typename L>
struct AlphabetSet : public Structure<AlphabetSet<L> > {};
}
template <typename L>
struct Element
{
Element()
{
op_is_finite(static_cast<const algebra::AlphabetSet<L>*>(0));
}
};
template <typename L>
bool op_is_finite(const algebra::AlphabetSet<L>*)
{
// This is the function we want to be called.
return true;
}
int main()
{
Element<char> alpha;
}
// % g++-3.4 -Wall -W temp1.cc
// % g++-4.2 -Wall -W temp1.cc
// temp1.cc: In function 'bool op_is_finite(const Structure<S>*) [with S =
algebra::AlphabetSet<char>]':
// temp1.cc:21: instantiated from 'Element<L>::Element() [with L = char]'
// temp1.cc:34: instantiated from here
// temp1.cc:7: error: cannot convert 'Structure<algebra::AlphabetSet<char> >'
to 'bool' in return
//////////////////////////////////////////////////////
//////////////// temp2.cc starts here ////////////////
//////////////////////////////////////////////////////
template<typename S> struct Structure {};
template<typename S>
bool op_is_finite (const Structure<S>*)
{
// Error on purpose, this function is not expected to be instantiated.
return Structure<S>();
}
template <typename L>
struct AlphabetSet : public Structure<AlphabetSet<L> > {};
template <typename L>
struct Element
{
Element()
{
op_is_finite(static_cast<const AlphabetSet<L>*>(0));
}
};
template <typename L>
bool op_is_finite(const AlphabetSet<L>*)
{
// This is the function that is called, as we expected.
return true;
}
int main()
{
Element<char> alpha;
}
// % g++-3.4 -Wall -W temp2.cc
// % g++-4.2 -Wall -W temp2.cc
--
Summary: overloaded template function resolves differently if one
type is included in a namespace
Product: gcc
Version: 4.2.3
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: adl at gnu dot org
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c++/34073] overloaded template function resolves differently if one type is included in a namespace
2007-11-12 15:21 [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace adl at gnu dot org
@ 2007-11-12 19:02 ` pinskia at gcc dot gnu dot org
2007-11-12 21:17 ` steven at gcc dot gnu dot org
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-11-12 19:02 UTC (permalink / raw)
To: gcc-bugs
------- Comment #1 from pinskia at gcc dot gnu dot org 2007-11-12 19:02 -------
And this is expected behavior of C++ Lookup in templates.
--
pinskia at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |INVALID
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c++/34073] overloaded template function resolves differently if one type is included in a namespace
2007-11-12 15:21 [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace adl at gnu dot org
2007-11-12 19:02 ` [Bug c++/34073] " pinskia at gcc dot gnu dot org
@ 2007-11-12 21:17 ` steven at gcc dot gnu dot org
2007-11-12 21:29 ` pinskia at gcc dot gnu dot org
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: steven at gcc dot gnu dot org @ 2007-11-12 21:17 UTC (permalink / raw)
To: gcc-bugs
------- Comment #2 from steven at gcc dot gnu dot org 2007-11-12 21:17 -------
Perhaps you can give a little more verbose explanation why this is invalid?
--
steven at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |pinskia at gcc dot gnu dot
| |org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c++/34073] overloaded template function resolves differently if one type is included in a namespace
2007-11-12 15:21 [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace adl at gnu dot org
2007-11-12 19:02 ` [Bug c++/34073] " pinskia at gcc dot gnu dot org
2007-11-12 21:17 ` steven at gcc dot gnu dot org
@ 2007-11-12 21:29 ` pinskia at gcc dot gnu dot org
2007-11-12 22:08 ` adl at gnu dot org
2007-11-20 11:30 ` [Bug c++/34073] New: " mahmoodn
4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-11-12 21:29 UTC (permalink / raw)
To: gcc-bugs
------- Comment #3 from pinskia at gcc dot gnu dot org 2007-11-12 21:29 -------
Basically the namelookup for op_is_finite in Element will lookup the previous
declared ones (at definition time) and then will do argument dependent lookup
(at instaintation time). Argument dependent lookup only looks at definition in
the namespace containing that argument type. So in the second case the
argument type (AlphabetSet) is in the global namespace so it will see the
function, while in the first case it is located in algebra namespace and there
is no matching function in that namespace.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c++/34073] overloaded template function resolves differently if one type is included in a namespace
2007-11-12 15:21 [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace adl at gnu dot org
` (2 preceding siblings ...)
2007-11-12 21:29 ` pinskia at gcc dot gnu dot org
@ 2007-11-12 22:08 ` adl at gnu dot org
2007-11-20 11:30 ` [Bug c++/34073] New: " mahmoodn
4 siblings, 0 replies; 6+ messages in thread
From: adl at gnu dot org @ 2007-11-12 22:08 UTC (permalink / raw)
To: gcc-bugs
------- Comment #4 from adl at gnu dot org 2007-11-12 22:08 -------
Thank you for the very clear explanation, Andrew.
Indeed, adding a "namespace algebra" around the second definition of
op_is_finite() will solve my problem.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace
2007-11-12 15:21 [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace adl at gnu dot org
` (3 preceding siblings ...)
2007-11-12 22:08 ` adl at gnu dot org
@ 2007-11-20 11:30 ` mahmoodn
4 siblings, 0 replies; 6+ messages in thread
From: mahmoodn @ 2007-11-20 11:30 UTC (permalink / raw)
To: gcc-bugs
Where are "temp1.cc" and "temp2.cc" so that I correct them? are they part of
the compiler?
Thanks,
pinskia at gcc dot gnu dot org wrote:
>
> Two files are appended at the end of this report: temp1.cc and temp2.cc.
>
> temp1.cc is the only file that causes a problem with recent releases
> of GCC. It contains :
>
> 1. a template definition of Structure<S>
> 2. a template definition of op_is_finite<S>(const Structure<S>*)
> 3. a template definition of algebra::AlphabetSet<L> inheriting from
> Structure
> 4. a template definition of Element<L>
> that calls op_is_finite(const algebra::AlphabetSet<L>*) in its ctor
> 5. a template overloaded definition for
> op_is_finite<L>(const
> algebra::AlphabetSet<L>*)
> 6. a main function that instantiate Element<char>.
>
> Because all definitions but main() are template, I expect the call to
> op_is_finite() in the ctor of Element<L> (#4) to be resolved during the
> instantiation of Element<char> (#6) after the second definition
> of op_is_finite() (#5) has been read. So the call would be bound
> to that second definition and not to the first.
>
> I have tested three GCC versions :
> g++-3.4 (GCC) 3.4.6 (Debian 3.4.6-6)
> g++-4.1 (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
> g++-4.2 (GCC) 4.2.3 20071014 (prerelease) (Debian 4.2.2-3)
>
> Both 4.1 and 4.2 behave identically: they seem to ignore the second
> definition of op_is_finite and try to call the first.
>
> 3.4 does what we expect: it calls the second definition.
>
>
> We have found at least two ways to alter temp1.cc such that 4.2 will
> compile it.
>
> - One is to move the second definition of op_is_finite() (#5) before its
> use in the constructor of Element<L> (#4).
>
> This ordering would make sense to me if the functions were not
> template, but it's not clear why this would change anything in
> the resolution of template overloaded functions. I might be
> missing something.
>
> - Another possibility is to move AlphabetSet<L> struct out of
> the "algebra::" namespace. temp2.cc contains the updated
> code.
>
> I'm really surprized that 4.2 compiles temp2.cc
> without problem and fails on temp1.cc.
>
>
>
>
> //////////////////////////////////////////////////////
> //////////////// temp1.cc starts here ////////////////
> //////////////////////////////////////////////////////
>
> template<typename S> struct Structure {};
>
> template<typename S>
> bool op_is_finite (const Structure<S>*)
> {
> // Error on purpose, this function is not expected to be instantiated.
> return Structure<S>();
> }
>
> namespace algebra
> {
> template <typename L>
> struct AlphabetSet : public Structure<AlphabetSet<L> > {};
> }
>
> template <typename L>
> struct Element
> {
> Element()
> {
> op_is_finite(static_cast<const algebra::AlphabetSet<L>*>(0));
> }
> };
>
> template <typename L>
> bool op_is_finite(const algebra::AlphabetSet<L>*)
> {
> // This is the function we want to be called.
> return true;
> }
>
> int main()
> {
> Element<char> alpha;
> }
>
> // % g++-3.4 -Wall -W temp1.cc
> // % g++-4.2 -Wall -W temp1.cc
> // temp1.cc: In function 'bool op_is_finite(const Structure<S>*) [with S =
> algebra::AlphabetSet<char>]':
> // temp1.cc:21: instantiated from 'Element<L>::Element() [with L =
> char]'
> // temp1.cc:34: instantiated from here
> // temp1.cc:7: error: cannot convert 'Structure<algebra::AlphabetSet<char>
> >'
> to 'bool' in return
>
> //////////////////////////////////////////////////////
> //////////////// temp2.cc starts here ////////////////
> //////////////////////////////////////////////////////
>
> template<typename S> struct Structure {};
>
> template<typename S>
> bool op_is_finite (const Structure<S>*)
> {
> // Error on purpose, this function is not expected to be instantiated.
> return Structure<S>();
> }
>
> template <typename L>
> struct AlphabetSet : public Structure<AlphabetSet<L> > {};
>
> template <typename L>
> struct Element
> {
> Element()
> {
> op_is_finite(static_cast<const AlphabetSet<L>*>(0));
> }
> };
>
> template <typename L>
> bool op_is_finite(const AlphabetSet<L>*)
> {
> // This is the function that is called, as we expected.
> return true;
> }
>
> int main()
> {
> Element<char> alpha;
> }
>
> // % g++-3.4 -Wall -W temp2.cc
> // % g++-4.2 -Wall -W temp2.cc
>
>
> --
> Summary: overloaded template function resolves differently if
> one
> type is included in a namespace
> Product: gcc
> Version: 4.2.3
> Status: UNCONFIRMED
> Severity: normal
> Priority: P3
> Component: c++
> AssignedTo: unassigned at gcc dot gnu dot org
> ReportedBy: adl at gnu dot org
> GCC build triplet: i686-pc-linux-gnu
> GCC host triplet: i686-pc-linux-gnu
> GCC target triplet: i686-pc-linux-gnu
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
>
>
>
--
View this message in context: http://www.nabble.com/-Bug-c%2B%2B-34073---New%3A-overloaded-template-function-resolves-differently-if-one-type-is-included-in-a-namespace-tf4791742.html#a13855273
Sent from the gcc - bugs mailing list archive at Nabble.com.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-11-20 11:30 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-12 15:21 [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace adl at gnu dot org
2007-11-12 19:02 ` [Bug c++/34073] " pinskia at gcc dot gnu dot org
2007-11-12 21:17 ` steven at gcc dot gnu dot org
2007-11-12 21:29 ` pinskia at gcc dot gnu dot org
2007-11-12 22:08 ` adl at gnu dot org
2007-11-20 11:30 ` [Bug c++/34073] New: " mahmoodn
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).