Archived

This forum has been archived. Please start a new discussion on GitHub.

Ice::ObjectPrx operator<< is in wrong namespace for argument dependent lookup.

Hi,

I'm using clang on apple:
$ c++ --version
Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix

I'm on OS X 10.8.2

I'm using Ice 3.5.0.

This .cpp file does not output the proxy correctly under clang.

#include <iostream>

using namespace std;

template<typename T>
void print(const T& t)
{
cout << t << endl;
}

#include <Ice/Ice.h>

int main()
{
Ice::CommunicatorPtr ic = Ice::initialize();
Ice::ObjectPrx prx = ic->stringToProxy("ProxyName:tcp -h hostname -p 1000");
print(prx);
return 0;
}

#if 0
namespace IceInternal {
ostream& operator <<(ostream& os, const Ice::ObjectPrx& px)
{
::operator << (os,px);
return os;
}
}
#endif

What happens is because there is no operator<< in the IceInternal namespace (it is in the global namespace), it converts the proxy to a bool and outputs "1" instead of the proxy string.

This code works with gcc 4.6, but not with clang. To get the code to work with clang, you can undo the #if 0 block. At that point, I inject an operator << into the IceInternal and argument dependent lookup starts working.

Comments

  • xdm
    xdm La Coruña, Spain
    Hi David,

    How did you compile the program? i cannot reproduce the issue using OS X 10.8 and same Clang version as you
    air:~ jose$ clang++ -v
    Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
    Target: x86_64-apple-darwin12.3.0
    Thread model: posix
    air:~ jose$ cat test.cpp 
    #include <iostream>
    
    using namespace std;
    
    template<typename T>
    void print(const T& t)
    {
    cout << t << endl;
    }
    
    #include <Ice/Ice.h>
    
    int main()
    {
    Ice::CommunicatorPtr ic = Ice::initialize();
    Ice::ObjectPrx prx = ic->stringToProxy("ProxyName:tcp -h hostname -p 1000");
    print(prx);
    return 0;
    }
    air:~ jose$ g++ test.cpp -I/Library/Developer/Ice-3.5.0/include/ -L/Library/Developer/Ice-3.5.0/lib -lIce -lIceUtil
    air:~ jose$ ./a.out 
    ProxyName -t -e 1.1:tcp -h hostname -p 1000
    
  • Here is my compile. One noteable difference is that I'm using -std=c++11 and -stdlib=libc++.

    dawilcox-MacBookPro1:we dawilcox$ c++ -o template template_main.cpp -I/usr/local/include -g -O0 -std=c++11 -stdlib=libc++ -lIce -lIceUtil
    dawilcox-MacBookPro1:we dawilcox$ ./template
    1
    dawilcox-MacBookPro1:we dawilcox$ cat template_main.cpp
    #include <iostream>

    using namespace std;

    template<typename T>
    void print(const T& t)
    {
    cout << t << endl;
    }

    #include <Ice/Ice.h>

    int main()
    {
    Ice::CommunicatorPtr ic = Ice::initialize();
    Ice::ObjectPrx prx = ic->stringToProxy("ProxyName:tcp -h hostname -p 1000");
    print(prx);
    return 0;
    }

    #if 0
    namespace IceInternal {
    ostream& operator <<(ostream& os, const Ice::ObjectPrx& px)
    {
    ::operator << (os,px);
    return os;
    }
    }
    #endif
  • xdm
    xdm La Coruña, Spain
    I was able to reproduce the issue, it works with Clang if you include Ice.h before the declaration of print. We will look into this in more detail, thanks for reporting the problem.