Bug 24702 - Koenig found functoid ref, but "cannot be used as a function"
Summary: Koenig found functoid ref, but "cannot be used as a function"
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-11-07 07:09 UTC by Mark Phillips
Modified: 2013-09-06 07:30 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2005-12-04 05:09:46


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Phillips 2005-11-07 07:09:06 UTC
The problem relates to functoid objects ("function like" objects, ie
ones with an operator() defined) and references to them within a 
namespace.  When Koenig lookup is used to find such a 
reference-to-functoid, g++ seems to find it okay, but then states 
"cannot be used as a function".  If I use an actual functoid object 
instead of a reference to one, it works fine.

Here is an example:

#include <iostream>

namespace dummyx {

  struct Dummy {
    Dummy() {}
  };

  struct DummyFunct {
    int operator()(Dummy d) const {return 5;}
    static DummyFunct& full() {static DummyFunct f; return f;}
  };
  static DummyFunct& dummyFunct=DummyFunct::full();

  DummyFunct myDummyFunct;

  DummyFunct& mymyDummyFunct=myDummyFunct;

}

int main() {

  ::dummyx::Dummy const d;

  std::cout<<"dummyx::dummyFunct(d) = "<<dummyx::dummyFunct(d)<<std::endl;
  std::cout<<"dummyFunct(d) = "<<dummyFunct(d)<<std::endl; // fails with 3.4 and 4.0
  std::cout<<"myDummyFunct(d) = "<<myDummyFunct(d)<<std::endl;
  std::cout<<"mymyDummyFunct(d) = "<<mymyDummyFunct(d)<<std::endl; // fails with 3.4 and 4.0

}

When I try to compile this code using g++ version 4.0.2 I get the
following errors:

testit.cc: In function ‘int main()’:
testit.cc:26: error: ‘dummyx::dummyFunct’ cannot be used as a function
testit.cc:28: error: ‘dummyx::mymyDummyFunct’ cannot be used as a function

I see no reason why such references should not be able to be used
as a function.  As you see, if it is explicitly namespace-qualified
it can be.  And according to Koenig rules, the unqualified name should
indeed be found and, as operator() is applicable for the found reference,
it should be usable as a function.  Indeed, this is what version 3.2.3
of g++ does.

The above test code compiles fine with g++ version 3.2.3.  The errors
seem only to occur in versions 3.4 and later (certainly they occur for 
versions 3.4.5 and 4.0.2.)

Additional version information:

  g++ (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-20)

  g++-3.4 (GCC) 3.4.5 20050809 (prerelease) (Ubuntu 3.4.4-6ubuntu8)

  g++-4.0 (GCC) 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)
Comment 1 Andrew Pinski 2005-11-07 13:36:58 UTC
Actually IIRC Koenig lookup only finds functions and not variables.  If that is the case we have two issues here.  One is we accept invalid and another is that error message is wrong.

Note ICC rejects this:
t.cc(26): error: identifier "dummyFunct" is undefined
    std::cout<<"dummyFunct(d) = "<<dummyFunct(d)<<std::endl; // fails with 3.4
                                   ^

t.cc(28): error: identifier "myDummyFunct" is undefined
    std::cout<<"myDummyFunct(d) = "<<myDummyFunct(d)<<std::endl;
                                     ^

t.cc(29): error: identifier "mymyDummyFunct" is undefined
    std::cout<<"mymyDummyFunct(d) = "<<mymyDummyFunct(d)<<std::endl; // fails
                                       ^
Comment 2 Mark Phillips 2005-11-09 01:33:19 UTC
The current C++ standard says that Koenig applies "when an unqualified 
name is used as the postfix-expression in a function call" which from
what I've read, must include the case of functoids/functors and references
to functoids/functors.

It is true that some people seem to be arguing that the standard be changed
to restrict Koenig to only functions, a view which seems to me rather
unfortunate.  However the fact remains that the current standard allows
functors and the g++ compiler complies with this by allowing functors.
The issue is that references to functors appear to be broken in the most
recent versions of g++.

I have written much code that relies on g++ finding references to functors
through Koenig lookup.  This code compiled fine with version 3.2.  The
problem only arose when I tried to update to the 4.0 compiler.
Comment 3 Gabriel Dos Reis 2005-11-16 19:28:18 UTC
Subject: Re:  Koenig found functoid ref, but "cannot be used as a function"

"pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| Actually IIRC Koenig lookup only finds functions and not variables. 

That is incorrect.  There is an active core language issue on
"argument dependent name lookup specification."

-- Gaby
Comment 4 Gabriel Dos Reis 2005-12-04 05:09:46 UTC
this issue should be resolved one way of the other based on the
core issue about argument dependent lookup specification, when a
non-function is found.  The "obvious" solution would be to do overload
resolution based on the signatures (whether actual function, constructor, 
function objects, or references to those).  However, all that needs
tracking the open core issue.
Comment 5 Paolo Carlini 2013-09-05 14:29:05 UTC
Gaby, can you help me with this old issue? I can't find any DR still open in this area, and we behave exactly like current clang & icc, that is we reject the last three lines (about unqualified dummyFunct, myDummyFunct, and mymyDummyFunct). Can we resolve this bug?
Comment 6 Jonathan Wakely 2013-09-05 14:40:27 UTC
The standard says:

When considering an associated namespace, the lookup is the same as the lookup performed when the associated namespace is used as a qualifier (3.4.3.2) except that:
- [...]
- [...]
- All names except those of (possibly overloaded) functions and function templates are ignored.

So non-functions are ignored.
Comment 7 Jonathan Wakely 2013-09-05 14:43:32 UTC
See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#218 for the rationale.
Comment 8 Paolo Carlini 2013-09-05 15:18:15 UTC
Thanks Jon!
Comment 9 Mark Phillips 2013-09-06 01:18:57 UTC
Thanks Jonathan for the information on the updated standard and the rationale behind restricting Koenig to actual functions and function templates.

In one way it is a bit of a pity - it does make functors second-class citizens compared to functions - but the linked document explains some additional considerations, namely the risk of over-visibility of names.  Perhaps it is a reasonable choice for now.  Hopefully a better solution will be introduced down the track (maybe extending it to functors, while at the same time narrowing/allowing-control-over namespaces to be looked up).
Comment 10 Jonathan Wakely 2013-09-06 07:30:35 UTC
I wouldn't hold your breath unfortunately. There are at least two opposing views on how to "fix" ADL within the standard committee and no consensus on what (if anything) should be done.