public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/53573] New: template type dependant name resolution broken
@ 2012-06-04 13:08 keean@fry-it.com
  2012-06-04 13:31 ` [Bug c++/53573] " keean@fry-it.com
                   ` (22 more replies)
  0 siblings, 23 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-04 13:08 UTC (permalink / raw)
  To: gcc-bugs

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

             Bug #: 53573
           Summary: template type dependant name resolution broken
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: keean@fry-it.com


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

* [Bug c++/53573] template type dependant name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
@ 2012-06-04 13:31 ` keean@fry-it.com
  2012-06-04 13:33 ` keean@fry-it.com
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-04 13:31 UTC (permalink / raw)
  To: gcc-bugs

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

Keean Schupke <keean@fry-it.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |keean@fry-it.com

--- Comment #1 from Keean Schupke <keean@fry-it.com> 2012-06-04 13:30:59 UTC ---
// test.cpp
//
// gcc-version: gcc (Gentoo 4.7.0 p1.0, pie-0.5.3) 4.7.0
// system-type: Linux Ra 3.0.29-tuxonice #4 SMP PREEMPT
//    Sat May 26 10:21:39 BST 2012
//    x86_64 Genuine Intel(R) CPU U7300 @ 1.30GHz GenuineIntel GNU/Linux
// compile options: g++ test.cpp
// compile output:
//    test.cpp: In instantiation of ‘T f(T) [with T = int]’:
//    test.cpp:27:9:   required from here
//    test.cpp:18:12: error: ‘g’ was not declared in this scope,
//    and no declarations were found by argument-dependent lookup
//    at the point of instantiation [-fpermissive]
//    test.cpp:21:5: note: ‘int g(int)’ declared here, later in the
//    translation unit

template <typename T> T f(T t) {
    return g(t);
}

int g(int x) {
    return x + 1;
}

main() {
    int x(1);
    x = f(x);
}


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

* [Bug c++/53573] template type dependant name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
  2012-06-04 13:31 ` [Bug c++/53573] " keean@fry-it.com
@ 2012-06-04 13:33 ` keean@fry-it.com
  2012-06-04 13:44 ` [Bug c++/53573] template type dependent " keean@fry-it.com
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-04 13:33 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Keean Schupke <keean@fry-it.com> 2012-06-04 13:33:38 UTC ---
The function called in the template definition is clearly dependent on the
template parameter 'T' and therefore itsname should be resolved at the point of
instantiation where 'g' is clearly defined and in scope (and is not local). The
error message says: "no declarations were found by argument-dependent lookup at
the point of instantiation" when 'g' should be found. See Technicalities C.13.8


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
  2012-06-04 13:31 ` [Bug c++/53573] " keean@fry-it.com
  2012-06-04 13:33 ` keean@fry-it.com
@ 2012-06-04 13:44 ` keean@fry-it.com
  2012-06-04 16:38 ` keean@fry-it.com
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-04 13:44 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Keean Schupke <keean@fry-it.com> 2012-06-04 13:44:14 UTC ---
From: Technicalities C.13.8.3: 

"   struct X { X(int); /* ... */ };
"
"   void g(X);
"
"   template<class T> void f(T a) { g(a); }
"
"   void h()
"   {
"       extern void g(int);
"       f(2); // invokes f(X(2)); that is, f<X>(X(2))
"   }
"
"   Here, the point of instantiation for f is just before h()...

Note: just before "h()", not just before "template<class T>"


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (2 preceding siblings ...)
  2012-06-04 13:44 ` [Bug c++/53573] template type dependent " keean@fry-it.com
@ 2012-06-04 16:38 ` keean@fry-it.com
  2012-06-04 17:13 ` keean@fry-it.com
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-04 16:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Keean Schupke <keean@fry-it.com> 2012-06-04 16:38:21 UTC ---
From C++ Standard N3242=11-0012 14.6 Name Resolution

10. If a name does not depend on a template-parameter (as defined in 14.6.2), a
declaration (or set of declarations) for that name shall be in scope at the
point where the name appears in the template definition; the name is bound to
the declaration (or declarations) found at that point and this binding is not
affected by declarations that are visible at the point of instantiation.
[Example:

    void f(char);

    template<class T> void g(T t) {
        f(1); // f(char)
        f(T(1)); // dependent
        f(t); // dependent
        dd++; // not dependent
        // error: declaration for dd not found
    }

    enum E { e };
    void f(E);

    double dd;
    void h() {
        g(e); // will cause one call of f(char) followed
        // by two calls of f(E)
        g(’a’); // will cause three calls of f(char)
    }

— end example ]


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (3 preceding siblings ...)
  2012-06-04 16:38 ` keean@fry-it.com
@ 2012-06-04 17:13 ` keean@fry-it.com
  2012-06-05  9:06 ` keean@fry-it.com
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-04 17:13 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Keean Schupke <keean@fry-it.com> 2012-06-04 17:13:18 UTC ---
The following program will apparently compile correctly, but will silently
produce incorrect results at runtime:



#include <iostream>

char g(char x) {
    return x - 1;
}

template <typename T> T f(T t) {
    return g(t);
}

int g(int x) {
    return x + 1;
}

main() {
    int x(1);
    int y(f(x));
    std::cout << y << "\n";
    int z(f<int>(x));
    std::cout << z << "\n";
}



This should print "2 2" but prints "0 0". Interestingly it also produces
incorrect results with gcc-4.6.3 and gcc-4.5.3. However the code below (which
does not compile on gcc-4.7.0 does produce the correct results on gcc-4.6.3 and
gcc-4.5.3:



#include <iostream>

template <typename T> T f(T t) {
    return g(t);
}

char g(char x) {
    return x - 1;
}

int g(int x) {
    return x + 1;
}

main() {
    int x(1);
    int y(f(x));
    std::cout << y << "\n";
    int z(f<int>(x));
    std::cout << z << "\n";
}



So it looks like earlier versions of GCC relied on 'g' being undefined at the
point of definition to defer binding until instantiation instead of looking for
dependence on a template parameter. gcc-4.7.0 does not seem to do either.

One more example:



#include <iostream>

class A {};

A g(A x) {
    return x;
}

template <typename T> T f(T t) {
    return g(t);
}

int g(int x) {
    return x + 1;
}

main() {
    int x(1);
    int y(f(x));
    std::cout << y << "\n";
    int z(f<int>(x));
    std::cout << z << "\n";
}



generates the following compile error:

test.cpp: In function ‘T f(T) [with T = int]’:
test.cpp:35:11:   instantiated from here
test.cpp:26:12: error: could not convert ‘t’ from ‘int’ to ‘A’


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (4 preceding siblings ...)
  2012-06-04 17:13 ` keean@fry-it.com
@ 2012-06-05  9:06 ` keean@fry-it.com
  2012-06-05 10:02 ` manu at gcc dot gnu.org
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-05  9:06 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Keean Schupke <keean@fry-it.com> 2012-06-05 09:06:01 UTC ---
The suggested work around in the error message 'adding -fpermissive' to
gcc-4.7.0 does not fix the problem as suggested by the error message. This
would suggest the compiler is not displaying the correct error message for the
problem.

g++ -fpermissive test.cpp

Still generates:

test.cpp: In instantiation of ‘T f(T) [with T = int]’:
test.cpp:27:9:   required from here
test.cpp:18:12: error: ‘g’ was not declared in this scope, and no declarations
were found by argument-dependent lookup at the point of instantiation
[-fpermissive]
test.cpp:21:5: note: ‘int g(int)’ declared here, later in the translation unit


A further test:



int g(int x) {
    return x + 1;
}

char g(char x) {
    return x - 1;
}

template <typename T> T f(T t) {
    return g((T)t);
}

double g(double x) {
    return x;
}

main() {
    double x(f(1.0L));
}



generates the following compile time error:


test.cpp: In instantiation of ‘T f(T) [with T = long double]’:
test.cpp:18:17:   required from here
test.cpp:10:15: error: call of overloaded ‘g(long double)’ is ambiguous
test.cpp:10:15: note: candidates are:
test.cpp:1:5: note: int g(int)
test.cpp:5:6: note: char g(char)



Which is interesting as it suggests that the overloading of 'g' is happening
from the definitions of 'g' that are in scope at the template definition. This
is quite strange behaviour, as the compiler must have to capture a list all
available overloads at the time of definition of each template. This looks like
a deliberate behaviour rather than a bug.

So this looks more like a misunderstanding of the specification is the cause of
this incorrect behaviour?


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (5 preceding siblings ...)
  2012-06-05  9:06 ` keean@fry-it.com
@ 2012-06-05 10:02 ` manu at gcc dot gnu.org
  2012-06-05 10:15 ` keean@fry-it.com
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: manu at gcc dot gnu.org @ 2012-06-05 10:02 UTC (permalink / raw)
  To: gcc-bugs

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

Manuel López-Ibáñez <manu at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |manu at gcc dot gnu.org

--- Comment #7 from Manuel López-Ibáñez <manu at gcc dot gnu.org> 2012-06-05 10:02:25 UTC ---
(In reply to comment #6)
> The suggested work around in the error message 'adding -fpermissive' to
> gcc-4.7.0 does not fix the problem as suggested by the error message. This
> would suggest the compiler is not displaying the correct error message for the
> problem.
> 
> g++ -fpermissive test.cpp
> 
> Still generates:
> 
> test.cpp: In instantiation of ‘T f(T) [with T = int]’:
> test.cpp:27:9:   required from here
> test.cpp:18:12: error: ‘g’ was not declared in this scope, and no declarations
> were found by argument-dependent lookup at the point of instantiation
> [-fpermissive]
> test.cpp:21:5: note: ‘int g(int)’ declared here, later in the translation unit
> 

With GCC 4.8 revision 187148, -fpermissive generates a warning as it should.
However, -fpermissive is not meant to fix anything, it is just a work-around to
make non-standard code compile.

I am not sure if this is a bug or not, so I am not touching the status.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (6 preceding siblings ...)
  2012-06-05 10:02 ` manu at gcc dot gnu.org
@ 2012-06-05 10:15 ` keean@fry-it.com
  2012-06-05 10:54 ` redi at gcc dot gnu.org
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-05 10:15 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Keean Schupke <keean@fry-it.com> 2012-06-05 10:15:18 UTC ---
(In reply to comment #7)
Have a read of the C++ standard, the example given in:

N3242=11-0012 14.6 Name Resolution: paragraph 10

Which I have pasted above into comment #4 and the extract from C++ Special
Edition (Technicalities C.13.8.3) which is pasted in comment #3.

How do you interpret these two? 


> (In reply to comment #6)
> > The suggested work around in the error message 'adding -fpermissive' to
> > gcc-4.7.0 does not fix the problem as suggested by the error message. This
> > would suggest the compiler is not displaying the correct error message for the
> > problem.
> > 
> > g++ -fpermissive test.cpp
> > 
> > Still generates:
> > 
> > test.cpp: In instantiation of ‘T f(T) [with T = int]’:
> > test.cpp:27:9:   required from here
> > test.cpp:18:12: error: ‘g’ was not declared in this scope, and no declarations
> > were found by argument-dependent lookup at the point of instantiation
> > [-fpermissive]
> > test.cpp:21:5: note: ‘int g(int)’ declared here, later in the translation unit
> > 
> 
> With GCC 4.8 revision 187148, -fpermissive generates a warning as it should.
> However, -fpermissive is not meant to fix anything, it is just a work-around to
> make non-standard code compile.
> 
> I am not sure if this is a bug or not, so I am not touching the status.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (7 preceding siblings ...)
  2012-06-05 10:15 ` keean@fry-it.com
@ 2012-06-05 10:54 ` redi at gcc dot gnu.org
  2012-06-05 11:03 ` redi at gcc dot gnu.org
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-05 10:54 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|major                       |normal

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-05 10:54:36 UTC ---
(In reply to comment #2)
> The function called in the template definition is clearly dependent on the
> template parameter 'T' and therefore itsname should be resolved at the point of
> instantiation where 'g' is clearly defined and in scope (and is not local). The
> error message says: "no declarations were found by argument-dependent lookup at
> the point of instantiation" when 'g' should be found. 

Built-in types have no associated namespaces so ADL can not find 'g' via ADL. A
declaration must be visible at the point of definition.

The example in comment 1 is ill-formed.

Paragraph 10 doesn't apply because the call is clearly dependent.

N.B. N3242 is not the C++ standard and neither is "C++ Special Edition" which
is quite old now.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (8 preceding siblings ...)
  2012-06-05 10:54 ` redi at gcc dot gnu.org
@ 2012-06-05 11:03 ` redi at gcc dot gnu.org
  2012-06-05 11:07 ` keean@fry-it.com
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-05 11:03 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID

--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-05 11:03:26 UTC ---
(In reply to comment #6)
> The suggested work around in the error message 'adding -fpermissive' to
> gcc-4.7.0 does not fix the problem as suggested by the error message. 

As Manu says, -fpermissive changes the error to a warning, allowing the code to
compile. Please check it again.

I'm going to close this, as I think G++ handles comment 1 correctly and both
EDG and Clang agree.

I didn't check all your other examples in detail but I don't think they show
anything different: ADL doesn't find anything for built-in types such as int or
char.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (9 preceding siblings ...)
  2012-06-05 11:03 ` redi at gcc dot gnu.org
@ 2012-06-05 11:07 ` keean@fry-it.com
  2012-06-05 11:14 ` keean@fry-it.com
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-05 11:07 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #11 from Keean Schupke <keean@fry-it.com> 2012-06-05 11:07:14 UTC ---
(In reply to comment #9)

Can you point me at where in the specification this is defined? 


> (In reply to comment #2)
> > The function called in the template definition is clearly dependent on the
> > template parameter 'T' and therefore itsname should be resolved at the point of
> > instantiation where 'g' is clearly defined and in scope (and is not local). The
> > error message says: "no declarations were found by argument-dependent lookup at
> > the point of instantiation" when 'g' should be found. 
> 
> Built-in types have no associated namespaces so ADL can not find 'g' via ADL. A
> declaration must be visible at the point of definition.
> 
> The example in comment 1 is ill-formed.
> 
> Paragraph 10 doesn't apply because the call is clearly dependent.
> 
> N.B. N3242 is not the C++ standard and neither is "C++ Special Edition" which
> is quite old now.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (10 preceding siblings ...)
  2012-06-05 11:07 ` keean@fry-it.com
@ 2012-06-05 11:14 ` keean@fry-it.com
  2012-06-05 11:26 ` keean@fry-it.com
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-05 11:14 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #12 from Keean Schupke <keean@fry-it.com> 2012-06-05 11:14:00 UTC ---
(In reply to comment #10)

although -fpermissive allows the code to compile (in some circumstances) it
does not in all, and it also produces incorrect output, for example:



#include <iostream>

char g(char x) {
    return x - 1;
}

template <typename T> T f(T t) {
    return g(t);
}

double g(double x) {
    return x;
}

main() {
    double x(f(1.0L));
    std::cout << x << "\n";
}



will output "0" instead of "1" choosing the wrong overloaded function. In the
case below:



#include <iostream>

char g(char x) {
    return x - 1;
}

int g(int x) {
    return x + 1;
}

template <typename T> T f(T t) {
    return g(t);
}

double g(double x) {
    return x;
}

main() {
    double x(f(1.0L));
    std::cout << x << "\n";
}



compilation still fails with:

test.cpp: In instantiation of ‘T f(T) [with T = long double]’:
test.cpp:20:17:   required from here
test.cpp:12:12: error: call of overloaded ‘g(long double&)’ is ambiguous
test.cpp:12:12: note: candidates are:
test.cpp:3:6: note: char g(char)
test.cpp:7:5: note: int g(int)

even with -fpermissive 

> (In reply to comment #6)
> > The suggested work around in the error message 'adding -fpermissive' to
> > gcc-4.7.0 does not fix the problem as suggested by the error message. 
> 
> As Manu says, -fpermissive changes the error to a warning, allowing the code to
> compile. Please check it again.
> 
> I'm going to close this, as I think G++ handles comment 1 correctly and both
> EDG and Clang agree.
> 
> I didn't check all your other examples in detail but I don't think they show
> anything different: ADL doesn't find anything for built-in types such as int or
> char.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (11 preceding siblings ...)
  2012-06-05 11:14 ` keean@fry-it.com
@ 2012-06-05 11:26 ` keean@fry-it.com
  2012-06-05 11:31 ` redi at gcc dot gnu.org
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-05 11:26 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #13 from Keean Schupke <keean@fry-it.com> 2012-06-05 11:25:40 UTC ---
(In reply to comment #9)

>From ISO14882 14.6 - Name resolution [temp.res]

-8- When looking for the declaration of a name used in a template definition,
the usual lookup rules (basic.lookup.unqual, basic.lookup.koenig) are used for
nondependent names. The lookup of names dependent on the template parameters is
postponed until the actual template argument is known (temp.dep). [Example:

#include <iostream>
using namespace std;

template<class T> class Set {
    T* p;
    int cnt;
public:
    Set();
    Set<T>(const Set<T>&);
    void printall()
    {
        for (int i = 0; i<cnt; i++)
            cout << p[i] << '\n';
    }
    //  ...
};
in the example, i is the local variable i declared in printall, cnt is the
member cnt declared in Set, and cout is the standard output stream declared in
iostream. However, not every declaration can be found this way; the resolution
of some names must be postponed until the actual template-arguments are known.
For example, even though the name operator<< is known within the definition of
printall() and a declaration of it can be found in <iostream>, the actual
declaration of operator<< needed to print p[i] cannot be known until it is
known what type T is (temp.dep). ]
-9- If a name does not depend on a template-parameter (as defined in temp.dep),
a declaration (or set of declarations) for that name shall be in scope at the
point where the name appears in the template definition; the name is bound to
the declaration (or declarations) found at that point and this binding is not
affected by declarations that are visible at the point of instantiation.
[Example:

void f(char);

template<class T> void g(T t)
{
    f(1);                   //   f(char)
    f(T(1));                //  dependent
    f(t);                   //  dependent
    dd++;                   //  not dependent
                //  error: declaration for dd not found
}
void f(int);

double dd;
void h()
{
    g(2);                   //  will cause one call of  f(char)  followed
                //   by two calls of  f(int)
    g('a');                 //  will cause three calls of  f(char)
}



So it was like this in 1998, and it is the same in the latest working draft. 


--- end example]

> (In reply to comment #2)
> > The function called in the template definition is clearly dependent on the
> > template parameter 'T' and therefore itsname should be resolved at the point of
> > instantiation where 'g' is clearly defined and in scope (and is not local). The
> > error message says: "no declarations were found by argument-dependent lookup at
> > the point of instantiation" when 'g' should be found. 
> 
> Built-in types have no associated namespaces so ADL can not find 'g' via ADL. A
> declaration must be visible at the point of definition.
> 
> The example in comment 1 is ill-formed.
> 
> Paragraph 10 doesn't apply because the call is clearly dependent.
> 
> N.B. N3242 is not the C++ standard and neither is "C++ Special Edition" which
> is quite old now.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (12 preceding siblings ...)
  2012-06-05 11:26 ` keean@fry-it.com
@ 2012-06-05 11:31 ` redi at gcc dot gnu.org
  2012-06-05 11:34 ` redi at gcc dot gnu.org
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-05 11:31 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #14 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-05 11:31:07 UTC ---
[temp.dep.res] says dependent name resolution considers declarations visible at
the point of definition, and declarations from associated namespaces from the
instantiation context and the definition context.

[basic.lookup.argdep]/2 says "If T is a fundamental type, its associated sets
of namespaces and classes are both empty."


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (13 preceding siblings ...)
  2012-06-05 11:31 ` redi at gcc dot gnu.org
@ 2012-06-05 11:34 ` redi at gcc dot gnu.org
  2012-06-05 11:53 ` keean@fry-it.com
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-05 11:34 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #15 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-05 11:33:59 UTC ---
(In reply to comment #12)
> (In reply to comment #10)
> 
> although -fpermissive allows the code to compile (in some circumstances) it
> does not in all, and it also produces incorrect output, for example:

-fpermissive is a kluge to allow non-standard code to compile, so *obviously*
it gives the wrong result in some cases, that's the point!

It allows comment 1 to compile, as the diagnostic indicates. If you don't like
the results of using -fpermissive then fix your code and don't use it.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (14 preceding siblings ...)
  2012-06-05 11:34 ` redi at gcc dot gnu.org
@ 2012-06-05 11:53 ` keean@fry-it.com
  2012-06-05 11:54 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-05 11:53 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #16 from Keean Schupke <keean@fry-it.com> 2012-06-05 11:53:32 UTC ---
(In reply to comment #14)

Basic.lookup.argdep is not specific to templates, so why does the dependent
lookup work outside of templates?

int g(int x) {
    return x - 1;
}

double g(double x) {
    return x + 1.0L;
}

main() {
    int x(g(1.0L));
}

why does ADL work here if [basic.lookup.argdep] means what you imply?




> [temp.dep.res] says dependent name resolution considers declarations visible at
> the point of definition, and declarations from associated namespaces from the
> instantiation context and the definition context.
> 
> [basic.lookup.argdep]/2 says "If T is a fundamental type, its associated sets
> of namespaces and classes are both empty."


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (15 preceding siblings ...)
  2012-06-05 11:53 ` keean@fry-it.com
@ 2012-06-05 11:54 ` redi at gcc dot gnu.org
  2012-06-05 11:57 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-05 11:54 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #16 from Keean Schupke <keean@fry-it.com> 2012-06-05 11:53:32 UTC ---
(In reply to comment #14)

Basic.lookup.argdep is not specific to templates, so why does the dependent
lookup work outside of templates?

int g(int x) {
    return x - 1;
}

double g(double x) {
    return x + 1.0L;
}

main() {
    int x(g(1.0L));
}

why does ADL work here if [basic.lookup.argdep] means what you imply?




> [temp.dep.res] says dependent name resolution considers declarations visible at
> the point of definition, and declarations from associated namespaces from the
> instantiation context and the definition context.
> 
> [basic.lookup.argdep]/2 says "If T is a fundamental type, its associated sets
> of namespaces and classes are both empty."

--- Comment #17 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-05 11:53:55 UTC ---
(In reply to comment #13)
> double dd;
> void h()
> {
>     g(2);                   //  will cause one call of  f(char)  followed
>                 //   by two calls of  f(int)
>     g('a');                 //  will cause three calls of  f(char)
> }
> 
> 
> 
> So it was like this in 1998, and it is the same in the latest working draft. 

(Please stop quoting large chunks of copyrighted documents.)

No it isn't the same, the example above was incorrect and different in C++11,
see DR 197: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#197


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (16 preceding siblings ...)
  2012-06-05 11:54 ` redi at gcc dot gnu.org
@ 2012-06-05 11:57 ` redi at gcc dot gnu.org
  2012-06-05 12:55 ` keean@fry-it.com
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-05 11:57 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #18 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-05 11:57:20 UTC ---
(In reply to comment #16)
> why does ADL work here if [basic.lookup.argdep] means what you imply?

That's not ADL, so I don't know what you're asking.

Bugzilla is not the right place to learn C++, please take this to an
appropriate forum.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (17 preceding siblings ...)
  2012-06-05 11:57 ` redi at gcc dot gnu.org
@ 2012-06-05 12:55 ` keean@fry-it.com
  2012-06-05 16:31 ` paolo.carlini at oracle dot com
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-05 12:55 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #19 from Keean Schupke <keean@fry-it.com> 2012-06-05 12:55:06 UTC ---
(In reply to comment #18)

Sorry about that. It does indeed seem that the combination of [temp.dep.res]
and [basic.lookup.argdep] imply this behaviour. I think my point was more about
why it is different from usual lookup, any you are quite right this is not the
place for that discussion. 

> (In reply to comment #16)
> > why does ADL work here if [basic.lookup.argdep] means what you imply?
> 
> That's not ADL, so I don't know what you're asking.
> 
> Bugzilla is not the right place to learn C++, please take this to an
> appropriate forum.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (18 preceding siblings ...)
  2012-06-05 12:55 ` keean@fry-it.com
@ 2012-06-05 16:31 ` paolo.carlini at oracle dot com
  2012-06-05 17:01 ` keean@fry-it.com
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: paolo.carlini at oracle dot com @ 2012-06-05 16:31 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #20 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-06-05 16:31:21 UTC ---
I'm under the impression that the bug reports using the word 'broken' are the
ones most likely broken, err invalid. Maybe just another manifestation of the
illusion of confidence, well known to the psychologjsts? (for a very nice intro
see, eg, Chabris & Simons, 'The invisible gorilla', Ch 3)


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (19 preceding siblings ...)
  2012-06-05 16:31 ` paolo.carlini at oracle dot com
@ 2012-06-05 17:01 ` keean@fry-it.com
  2012-06-05 17:30 ` redi at gcc dot gnu.org
  2012-06-27  6:48 ` keean@fry-it.com
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-05 17:01 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #21 from Keean Schupke <keean@fry-it.com> 2012-06-05 17:01:01 UTC ---
(In reply to comment #20)

Yes, once again sorry. Obviously not GCC's problem for implementing the
standard correctly, but this causes problems producing elegant datatype generic
code. For example if a concept is defined in a library (using Boost Concept
Checking for example) and I want to make 'int' comply to that concept, I would
have to declare the new int methods before including the library. This seems
very odd in end user code. 

In this case there is nothing intuitively wrong with the way GCC was doing it -
it was not difficult for the compiler authors to implement, and nor did it lead
to incorrect or hard to understand code, in fact it worked very well for
generic programming.

Is there any chance this 'feature' of GCC could be kept as a g++ specific
extension in 'gnu++11' mode, as I think the old behaviour is an improvement
over that suggested in the standard, and GCC provides other extensions to
standard behaviour where it is useful.


> I'm under the impression that the bug reports using the word 'broken' are the
> ones most likely broken, err invalid. Maybe just another manifestation of the
> illusion of confidence, well known to the psychologjsts? (for a very nice intro
> see, eg, Chabris & Simons, 'The invisible gorilla', Ch 3)


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (20 preceding siblings ...)
  2012-06-05 17:01 ` keean@fry-it.com
@ 2012-06-05 17:30 ` redi at gcc dot gnu.org
  2012-06-27  6:48 ` keean@fry-it.com
  22 siblings, 0 replies; 24+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-05 17:30 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #22 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-05 17:30:18 UTC ---
(In reply to comment #21)
> Is there any chance this 'feature' of GCC could be kept as a g++ specific
> extension in 'gnu++11' mode, as I think the old behaviour is an improvement
> over that suggested in the standard, and GCC provides other extensions to
> standard behaviour where it is useful.

I doubt it. The old behaviour was the source of several long-standing bug
reports. Now G++ implements the standard's required behaviour and agrees with
other leading compilers.  GNU extensions usually allow new features by
supporting new syntax not by changing the meaning of valid code, it would not
be a pure extension.


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

* [Bug c++/53573] template type dependent name resolution broken
  2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
                   ` (21 preceding siblings ...)
  2012-06-05 17:30 ` redi at gcc dot gnu.org
@ 2012-06-27  6:48 ` keean@fry-it.com
  22 siblings, 0 replies; 24+ messages in thread
From: keean@fry-it.com @ 2012-06-27  6:48 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #23 from Keean Schupke <keean@fry-it.com> 2012-06-27 06:48:28 UTC ---
(In reply to comment #22)
> (In reply to comment #21)
> > Is there any chance this 'feature' of GCC could be kept as a g++ specific
> > extension in 'gnu++11' mode, as I think the old behaviour is an improvement
> > over that suggested in the standard, and GCC provides other extensions to
> > standard behaviour where it is useful.
> 
> I doubt it. The old behaviour was the source of several long-standing bug
> reports. Now G++ implements the standard's required behaviour and agrees with
> other leading compilers.  GNU extensions usually allow new features by
> supporting new syntax not by changing the meaning of valid code, it would not
> be a pure extension.

I have started a discussion on the C++ Standard discussion group about whether
the code in the original example should work. So far the only responses have
been to indicate that the code I posted is intended to work. Anyone wishing to
discuss this further should post there:

https://groups.google.com/a/isocpp.org/d/msg/std-discussion/OABibx-FK-o/srhSRlQduJAJ


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

end of thread, other threads:[~2012-06-27  6:48 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-04 13:08 [Bug c++/53573] New: template type dependant name resolution broken keean@fry-it.com
2012-06-04 13:31 ` [Bug c++/53573] " keean@fry-it.com
2012-06-04 13:33 ` keean@fry-it.com
2012-06-04 13:44 ` [Bug c++/53573] template type dependent " keean@fry-it.com
2012-06-04 16:38 ` keean@fry-it.com
2012-06-04 17:13 ` keean@fry-it.com
2012-06-05  9:06 ` keean@fry-it.com
2012-06-05 10:02 ` manu at gcc dot gnu.org
2012-06-05 10:15 ` keean@fry-it.com
2012-06-05 10:54 ` redi at gcc dot gnu.org
2012-06-05 11:03 ` redi at gcc dot gnu.org
2012-06-05 11:07 ` keean@fry-it.com
2012-06-05 11:14 ` keean@fry-it.com
2012-06-05 11:26 ` keean@fry-it.com
2012-06-05 11:31 ` redi at gcc dot gnu.org
2012-06-05 11:34 ` redi at gcc dot gnu.org
2012-06-05 11:53 ` keean@fry-it.com
2012-06-05 11:54 ` redi at gcc dot gnu.org
2012-06-05 11:57 ` redi at gcc dot gnu.org
2012-06-05 12:55 ` keean@fry-it.com
2012-06-05 16:31 ` paolo.carlini at oracle dot com
2012-06-05 17:01 ` keean@fry-it.com
2012-06-05 17:30 ` redi at gcc dot gnu.org
2012-06-27  6:48 ` keean@fry-it.com

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