Search code examples
c++clangshared-ptrgoogle-nativeclient

Clang 4.6.2, use shared_ptr


From PNaCl, I use libstdc++ to compile same code. But I want use shared_ptr and I obtain this error :

error: call to implicitly-deleted copy constructor of

This problem have issue :

Using std::shared_ptr with clang++ and libstdc++

I understand, but I don't know how resolve this. I quote the solution :

Adding a defaulted copy constructor and copy assignment operator to shared_ptr will fix the problem.

I add this in shared_ptr.h:

shared_ptr(const shared_ptr&) noexcept = default;

But compiler returns now this error :

F:/nacl_sdk/pepper_31/toolchain/win_pnacl/usr/include/c++/4.6.2/bits/shared_ptr.
h:268:19: error:
  exception specification of explicitly defaulted copy assignment operator
  does not match the calculated one
  shared_ptr& operator=(const shared_ptr&) noexcept = default;
              ^

In this chain of error, I finish here.

Somebody have tips, please?


Solution

  • I was able to repro your bug with this simple test case:

    #include <memory>
    
    int main() {
      std::shared_ptr<int> foo;
      std::shared_ptr<int> bar(foo);
      std::shared_ptr<int> baz;
      baz = foo;
      return 0;
    }
    

    Building with pnacl-clang++ -std=c++11 -stdlib=libstdc++ test.cc

    The easiest way to fix it it is to use libc++ instead of libstdc++:

    pnacl-clang++ -std=c++11 -stdlib=libc++ test.cc

    This is "experimental" in pepper_31, but will be the default in pepper_33 and higher (which is currently pepper_canary). See https://groups.google.com/forum/#!topic/native-client-discuss/0spfg6O04FM for more info about this switch.

    I was also able to hack two headers to make it work with libstdc++:

    In bits/shared_ptr.h:

    template<typename _Tp>
    class shared_ptr : public __shared_ptr<_Tp>
    {
    public:
      shared_ptr(const shared_ptr&) = default;
      shared_ptr& operator =(const shared_ptr&) = default;
      ...
    

    In bits/shared_ptr_base.h:

    template<typename _Tp, _Lock_policy _Lp>
    class __shared_ptr
    {
    public:
      __shared_ptr(const __shared_ptr&) = default;
      __shared_ptr& operator =(const __shared_ptr&) = default;
      ...
    

    IMO, using libc++ is a better solution here. :)