This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace
- From: mahmoodn <nt_mahmood at yahoo dot com>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 20 Nov 2007 03:30:36 -0800 (PST)
- Subject: Re: [Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace
- References: <bug-34073-5329@http.gcc.gnu.org/bugzilla/>
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.