public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/34322]  New: template fails to resolve names even when the name is in scope before the call point
@ 2007-12-03  6:05 logicle at live dot com
  2007-12-03  6:11 ` [Bug c++/34322] " logicle at live dot com
  2007-12-03 12:56 ` pinskia at gcc dot gnu dot org
  0 siblings, 2 replies; 3+ messages in thread
From: logicle at live dot com @ 2007-12-03  6:05 UTC (permalink / raw)
  To: gcc-bugs

This code reproduces the problem with gcc-4.x, but compiles fine with prior
versions of gcc and with other compilers. The error output differs depending on
what exactly is parsed, but I believe this example illustrates the general
change in behavior. 

FILE: header1.h
------------------------------------------
#ifndef _INCLUDED_Header1_H
#define _INCLUDED_Header1_H

#include <string>

namespace N
{
    const std::string & resolveName(const int &)
    {
        static const std::string & name = "int";
        return name;
    }
    const std::string & getName(const int & v)
    {
        return resolveName(v);
    }

    template<typename ValueType>
        const std::string & getName(const ValueType & v)
    {
        return resolveName(v);
    }
}

#endif//_INCLUDED_Header1_H

------------------------------------------

FILE: main.cpp
------------------------------------------
#include <string>
#include "header1.h"

class A
{
public:
    A() { }
    ~A() { }
};

namespace N
{
    const std::string & resolveName(const A &)
    {
        static const std::string name = "A";
        return name;
    }
}

int main(int, char **)
{
    int result = 0;
    const std::string & resultName = N::getName(result);

    A a;
    const std::string & name = N::getName(a); // <- fails to find
N::resolveName(const A &)
    // while processing
    // template<typename ValueType> const std::string & getName(const ValueType
&) from
    // header1.h unless the above N::resolveName(const A &) is declared BEFORE
    // header1.h is included, though the point of resolution appears AFTER
    // both header1.h is included and N::resolveName(const A&) is defined.
    // This behavior is new to gcc-4 and not present in most other compilers
    // including gcc prior to version 4.

    return result;
}

------------------------------------------

g++ -c main.cpp
header1.h: In function &#8216;const std::string& N::getName(const ValueType&)
[with ValueType = A]&#8217;:
main.cpp:26:   instantiated from here
header1.h:21: error: invalid initialization of reference of type &#8216;const
int&&#8217; from expression of type &#8216;const A&#8217;
header1.h:8: error: in passing argument 1 of &#8216;const std::string&
N::resolveName(const int&)&#8217;


Changing main.cpp to include header1.h AFTER resolveName(const A &) is declared
works around this issue:

FILE: main.cpp
------------------------------------------
#include <string>

class A
{
public:
    A() { }
    ~A() { }
};

namespace N
{
    const std::string & resolveName(const A &)
    {
        static const std::string name = "A";
        return name;
    }
}

#include "header1.h"

int main(int, char **)
{
    int result = 0;
    const std::string & resultName = N::getName(result);

    A a;
    const std::string & name = N::getName(a); 
    return result;
}

------------------------------------------

In this contrived example, the workaround is straightforward and easy to
implement. In a larger codebase, the workarounds are difficult to implement or
even discern. I'm not sure what happens if there is some complex cyclic
dependency introduced now that parsing order is significant.

In my case specifically, I use namespaces to arbitrarily extend functionality
for client code as long as the user declares new methods in scope of the type
they are compiling. (e.g. serializing a complex, user-defined type).

Does the standard require this behavior, or is this an optimization that has
broken code that does not have gcc-4 correct ordering of its headers?


-- 
           Summary: template fails to resolve names even when the name is in
                    scope before the call point
           Product: gcc
           Version: 4.1.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: logicle at live dot com
 GCC build triplet: linux 2.6.23 x86_64
  GCC host triplet: linux 2.6.23 x86_64
GCC target triplet: linux 2.6.23 x86_64


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34322


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/34322] template fails to resolve names even when the name is in scope before the call point
  2007-12-03  6:05 [Bug c++/34322] New: template fails to resolve names even when the name is in scope before the call point logicle at live dot com
@ 2007-12-03  6:11 ` logicle at live dot com
  2007-12-03 12:56 ` pinskia at gcc dot gnu dot org
  1 sibling, 0 replies; 3+ messages in thread
From: logicle at live dot com @ 2007-12-03  6:11 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from logicle at live dot com  2007-12-03 06:11 -------
Created an attachment (id=14685)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14685&action=view)
Source files reproducing the bug

compile with g++ -c main.cpp


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34322


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/34322] template fails to resolve names even when the name is in scope before the call point
  2007-12-03  6:05 [Bug c++/34322] New: template fails to resolve names even when the name is in scope before the call point logicle at live dot com
  2007-12-03  6:11 ` [Bug c++/34322] " logicle at live dot com
@ 2007-12-03 12:56 ` pinskia at gcc dot gnu dot org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-12-03 12:56 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from pinskia at gcc dot gnu dot org  2007-12-03 12:56 -------
GCC 4.1 (and above) is correct, the overloaded set of resolveName should be
either the direct namespace of which A resides (the global one) or the ones
which are defined before getName.  
This is the specific template namelookup rules for dependent arguments.

if you want getName to find the correct resolveName here, define resolveName in
the same namespace as A is defined (aka the global namespace). 


-- 

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=34322


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-12-03 12:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-03  6:05 [Bug c++/34322] New: template fails to resolve names even when the name is in scope before the call point logicle at live dot com
2007-12-03  6:11 ` [Bug c++/34322] " logicle at live dot com
2007-12-03 12:56 ` pinskia at gcc dot gnu dot org

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).