public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "adl at gnu dot org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/34073]  New: overloaded template function resolves differently if one type is included in a namespace
Date: Mon, 12 Nov 2007 15:21:00 -0000	[thread overview]
Message-ID: <bug-34073-5329@http.gcc.gnu.org/bugzilla/> (raw)

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


             reply	other threads:[~2007-11-12 15:21 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-12 15:21 adl at gnu dot org [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-34073-5329@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).