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
next 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: linkBe 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).