Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

std::bind error with Intel C++ 14.0.1 and libc++ on OS X

David_S_
Beginner
1,134 Views

I am using the Intel C++ compiler on OS X 10.9 and 10.9.1, and am encountering a problem with std::bind.

The following snippet compiles correctly using clang 5.0 (clang-500.2.79) shipped with Xcode 5.0.2, or with g++ 4.8 (MacPorts gcc48 4.8.2_0):

[cpp]#include <iostream>

#include <functional>

void test(int v);

int main(int argc, char* argv[])

{

    int v = 1;

    auto f = std::bind(test, std::placeholders::_1);

    f(v);

    return(EXIT_SUCCESS);

}

void test(int v)

{

    std::cout << "Called test with argument v = " << v << std::endl;

}[/cpp]

However, compiling with Intel C++ gives a compiler error:

[bash]icpc -std=c++11 -stdlib=libc++ -o test test.cpp

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/type_traits(2954): error: function "std::__1::__nat::~__nat()" (declared at line 854) cannot be referenced -- it is a deleted function

              __invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)

              ^

          detected during:

            instantiation of class "std::__1::__invokable_imp<_Fp, _Args...> [with _Fp=std::__1::placeholders::__ph<1> &, _Args=<int &>]" at line 2962

            instantiation of class "std::__1::__invokable<_Fp, _Args...> [with _Fp=std::__1::placeholders::__ph<1> &, _Args=<int &>]" at line 2981

            instantiation of class "std::__1::__invoke_of<_Fp, _Args...> [with _Fp=std::__1::placeholders::__ph<1> &, _Args=<int &>]" at line 1691 of "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/functional"

            instantiation of "std::__1::__bind_return<_Fp, _BoundArgs, _Args, std::__1::_is_valid_bind_return<_Fp, _BoundArgs, _Args>::value>::type std::__1::__apply_functor(_Fp &, _BoundArgs &, std::__1::__tuple_indices<_Indx...>, _Args &&) [with _Fp=void (*)(int), _BoundArgs=std::__1::tuple<std::__1::placeholders::__ph<1>>, _Indx=<0UL>, _Args=std::__1::tuple<int &>]" at line 1753 of "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/functional"

            instantiation of "std::__1::__bind_return<std::__1::decay<_Fp>::type, std::__1::tuple<std::__1::decay<_BoundArgs>::type...>, std::__1::tuple<_Args &&...>, std::__1::_is_valid_bind_return<std::__1::decay<_Fp>::type, std::__1::tuple<std::__1::decay<_BoundArgs>::type...>, std::__1::tuple<_Args &&...>>::value>::type std::__1::__bind<_Fp, _BoundArgs...>::operator()(_Args &&...) [with _Fp=void (&)(int), _BoundArgs=<std::__1::placeholders::__ph<1> &>, _Args=<int &>]" at line 11 of

                      "test.cpp"

compilation aborted for test.cpp (code 2)[/bash]

If I have understood correctly, this seems to be a problem with the compiler's handling of libc++. I have tried using the switches --gcc-name and --g++-name to force the compiler to use the headers provided with gcc 4.8, but this doesn't seem to have the correct effect at all; it forces the compiler to fall back on the gcc 4.2 headers shipped with Xcode:

[bash]icpc -H -std=c++11 -gxx-name=g++-mp-4.8 -gcc-name=gcc-mp-4.8 -o test test.cpp

. /usr/include/c++/4.2.1/iostream

.. /usr/include/c++/4.2.1/bits/c++config.h

... /usr/include/c++/4.2.1/bits/os_defines.h

.... /usr/include/unistd.h

..... /usr/include/_types.h

[snip][/bash]

Should I regard both these problems as compiler bugs?

0 Kudos
12 Replies
Andrey_B_Intel2
Employee
1,134 Views

Hi David,

First of all, thanks for reporting this -- errors with using std::bind from libc++ is definitely a problem and should be fixed. We are working on this; I will update this thread with new data when it will become available.

As for explicitly setting path for GNU headers, let me investigate a bit more and get back to you tomorrow.

Yours,
Andrey

0 Kudos
Andrey_B_Intel2
Employee
1,134 Views

David,

[David S. wrote:
If I have understood correctly, this seems to be a problem with the compiler's handling of libc++. I have tried using the switches --gcc-name and --g++-name to force the compiler to use the headers provided with gcc 4.8, but this doesn't seem to have the correct effect at all; it forces the compiler to fall back on the gcc 4.2 headers shipped with Xcode:

These options set names of gcc / g++ compilers -- and nothing more. They don't affect headers search patch.

To change search path for GCC headers, use GXX_INCLUDE environment variable:

export GXX_INCLUDE=/users/davids/gcc4.8/include/

Also, don't forget to either set LIBRARY_PATH or add -L as appropriate to linker options -- to make sure correct version of GCC libraries is linked.

Andrey

0 Kudos
Andrey_B_Intel2
Employee
1,134 Views

Hi David,

Could you, please, post a test case that leads to errors associated with casts from std::bind to std::function?

We will investigate.

Yours,
Andrey
 

0 Kudos
Andrey_B_Intel2
Employee
1,134 Views

David,

Thanks for the reproducer! -- again, let me investigate and get back to you in a day or two.

Andrey

 

0 Kudos
David_S_
Beginner
1,134 Views

Thanks very much for this. Just in case it is of help:

  • I checked this example using the Linux version of the 14.0.1 compiler, and it reproduces the same error. On this installation, icpc is using the gcc 4.8.1 headers.
  • On version 13.3, this snippet needs to be changed because the compiler complains about a missing return statement in find_item(). After doing so, the compiler fails slightly differently:
    [plain]bindtest.cpp(38): internal error: assertion failed at: "shared/cfe/edgcpfe/lower_name.c", line 8771[/plain]
0 Kudos
David_S_
Beginner
1,134 Views

Andrey Bokhanko (Intel) wrote:

Could you, please, post a test case that leads to errors associated with casts from std::bind to std::function?

Thanks very much for following this up.

The pattern which seems to cause trouble is something like:

[cpp]

#include <iostream>

#include <functional>

#include <string>

 

template <typename T>

class item

{

public:

};

 

template <typename T>

class item_manager

{

public:

    typedef std::function< item<T>*(const std::string&) > item_finder;

    item_finder item_finder_factory()

    {

      return(std::bind(&item_manager<T>::find_item, this, std::placeholders::_1));

    }

 

protected:

   item<T>* find_item(const std::string& i);

};

 

template <typename T>

item<T>* item_manager<T>::find_item(const std::string& i)

{    

}

 

int main(int argc, char* argvp[])

{

    item_manager<double> mgr;

    item_manager<double>::item_finder f = mgr.item_finder_factory();

}

[/cpp]

This compiles correctly with clang++ and gcc 4.8, but fails with the Intel compiler:

[plain]

[17:58:52 ds283@adur bind-test]$ icpc -gcc-name=/opt/local/bin/gcc-mp-4.8 -gxx-name=/opt/local/bin/g++-mp-4.8 -gcc-version=480 -I/opt/local/include/gcc48/c++ -I/opt/local/include/gcc48/c++/x86_64-apple-darwin13 -std=c++11 -stdlib=libstdc++ -L/opt/local/lib/gcc48 -o bindtest bindtest.cpp 

icpc: command line remark #10010: option '-gcc-version=480' is deprecated and will be removed in a future release. See '-help deprecated'

bindtest.cpp(19): error: no suitable user-defined conversion from "std::_Bind<std::_Mem_fn<item<double> *(item_manager<double>::*)(const std::string &)> (item_manager<double> *, std::_Placeholder<1>)>" to "std::function<item<double> *(const std::string &)>" exists

        return(std::bind(&item_manager<T>::find_item, this, std::placeholders::_1));

              ^

          detected during instantiation of "item_manager<T>::item_finder item_manager<T>::item_finder_factory() [with T=double]" at line 35

compilation aborted for bindtest.cpp (code 2)

[/plain]

I see this with both my own code and a library, odeint-v2, which is part of Boost (http://headmyshoulder.github.io/odeint-v2).

0 Kudos
David_S_
Beginner
1,134 Views

Thanks for this. I see I had misunderstood how I was supposed to point the compiler to the GCC headers.

I now have a different problem of forcing the compiler to enter gcc 4.8 compatibility  mode. This time, I think I really am supposed to use the -gcc-name and -gxx-name switches, but they do nothing:

[plain]

[09:21:46 ds283@taff gcc48]$ icpc -v

icpc version 14.0.1 (gcc version 4.2.1 compatibility)

[/plain]

[plain]

[10:18:48 ds283@taff gcc48]$ /opt/local/bin/gcc-mp-4.8 --version

gcc-mp-4.8 (MacPorts gcc48 4.8.2_0) 4.8.2

Copyright (C) 2013 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

[10:19:27 ds283@taff gcc48]$ /opt/local/bin/g++-mp-4.8 --version

g++-mp-4.8 (MacPorts gcc48 4.8.2_0) 4.8.2

Copyright (C) 2013 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

[10:19:53 ds283@taff gcc48]$ icpc -gcc-name=/opt/local/bin/gcc-mp-4.8 -gxx-name=/opt/local/bin/gxx-mp-4.8 -v

icpc version 14.0.1 (gcc version 4.2.1 compatibility)

[/plain]

Only when I use the deprecated option -gcc-version do I see a change:

[plain]

[10:19:57 ds283@taff gcc48]$ icpc -gcc-name=/opt/local/bin/gcc-mp-4.8 -gxx-name=/opt/local/bin/gxx-mp-4.8 -gcc-version=480 -v

icpc: command line remark #10010: option '-gcc-version=480' is deprecated and will be removed in a future release. See '-help deprecated'

icpc version 14.0.1 (gcc version 4.8.0 compatibility)

[/plain]

This gives the expected behaviour, and allows icpc to process the GCC headers. Unsurprisingly, In 4.2.1 compatibility mode I see a lot of errors when trying to compile against the 4.8 headers.

Forcing the compiler to use 4.8.0 compatibility mode, I see a different set of errors associated with casts from std::bind to std::function. I seem unable to post the error messages because they trigger the spam filter, but the code compiles cleanly with clang. Can I ask if there are also known issues of this type with libstdc++?

0 Kudos
Sergey_M_Intel
Employee
1,134 Views

David,

we have reproduced this issue and investigating it. We will tell you investigation results.

0 Kudos
Sergey_M_Intel
Employee
1,134 Views

David,

Sorry for delayed response. I have recognized that libstdc++48 compfail (your last reproducer) is compiler issue. We will work on this issue.

--Sergey

0 Kudos
David_S_
Beginner
1,134 Views

Thanks for the update. I appreciate your efforts in looking into this.

David

0 Kudos
Andrey_A_1
Beginner
1,134 Views

Here's another snippet of code with the same header issue on a mac with icpc version 14.0.1 (gcc version 4.2.1 compatibility)

[cpp]#include <functional>

struct dummy
{
    typedef std::function<int(int)> f_type;
    f_type x_; 
    dummy(f_type x):x_(x){x(0);};
};

dummy get_dummy()
{
    return dummy([](int i)->int{return 2;});
}

int main(int argc, char* argv[])
{
    get_dummy();
}

[/cpp]

which gives
[plain]$ icpc -std=c++11 -stdlib=libc++ test2.cpp -o test2

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/type_traits(2954): error: function "std::__1::__nat::~__nat()" (declared at line 854) cannot be referenced -- it is a deleted function
              __invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)
              ^
          detected during:
            instantiation of class "std::__1::__invokable_imp<_Fp, _Args...> [with _Fp=dummy &, _Args=<int>]" at line 2962
            instantiation of class "std::__1::__invokable<_Fp, _Args...> [with _Fp=dummy &, _Args=<int>]" at line 12 of "test2.cpp"

compilation aborted for test2.cpp (code 2)[/plain]
0 Kudos
Sergey_M_Intel
Employee
1,134 Views

Andrey A, thanks!

It's known issue. It will be fixed in a one of the future releases.

--Sergey

0 Kudos
Reply