STLPort and shared_ptr

1,770 views
Skip to first unread message

Jeffrey Walton

unread,
Jul 21, 2013, 12:02:12 AM7/21/13
to Android NDK List
Hi All,

shared_ptr has been around since the TR1 days. When I try and use it,
I get the following: "error: 'std::shared_ptr' has not been declared"

I found it in <memory> through grep; but it appears its pretty much
left undefined (if I am reading all the conditional compiles
correctly).

Any ideas how to use shared_ptr in the STLPort included with Android's NDK?

Jeff

riemann::stlport$ arm-linux-androideabi-g++ -fpic
-DSAFEINT_DISALLOW_UNSIGNED_NEGATION=1 -pipe -fsigned-char
-Woverloaded-virtual -Wreorder -Wconversion -Wmissing-declarations
-Wformat=2 -Wformat-security -Wuninitialized -Wno-unused
-fstrict-aliasing -fvisibility=hidden -fstack-protector-all
-Wstrict-overflow -Wall -Wextra -Wno-unused -Wno-type-limits
-Wtrampolines -std=c++0x -I. -I./esapi -I./deps
-I/opt/android-ndk-r8e//sources/cxx-stl/stlport/stlport/
--sysroot=/opt/android-ndk-r8e//platforms/android-14/arch-arm -c
src/EncoderConstants.cpp -o src/EncoderConstants.o
In file included from src/EncoderConstants.cpp:11:0:
./esapi/EsapiCommon.h:157:12: error: 'std::shared_ptr' has not been declared
./esapi/EsapiCommon.h:158:12: error: 'std::unordered_map' has not been declared
make: *** [src/EncoderConstants.o] Error 1

**********

riemann::stlport$ grep -r shared_ptr .
./memory:template<class T> class shared_ptr;
./memory:template<class D, class T> D * get_deleter(shared_ptr<T> const & p);
./memory:template<class T, class U> shared_ptr<T>
static_pointer_cast(shared_ptr<U> const & r);
./memory:template<class T, class U> shared_ptr<T>
const_pointer_cast(shared_ptr<U> const & r);
./memory:template<class T, class U> shared_ptr<T>
dynamic_pointer_cast(shared_ptr<U> const & r);
./memory:template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b);
./memory:# include <boost/shared_ptr.hpp>
./memory:using ::boost::shared_ptr;
./memory:// shared_ptr IO

**********

riemann::stlport$ cat memory
...

namespace boost {

class bad_weak_ptr;
template<class T> class shared_ptr;
template<class T> class weak_ptr;
template<class T> class enable_shared_from_this;
template<class D, class T> D * get_deleter(shared_ptr<T> const & p);
template<class T, class U> shared_ptr<T>
static_pointer_cast(shared_ptr<U> const & r);
template<class T, class U> shared_ptr<T>
const_pointer_cast(shared_ptr<U> const & r);
template<class T, class U> shared_ptr<T>
dynamic_pointer_cast(shared_ptr<U> const & r);
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b);
template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b);

namespace detail{
class shared_count;
class weak_count;
}

} // namespace boost

# ifndef BOOST_SHARED_PTR_HPP_INCLUDED
# include <boost/shared_ptr.hpp>
# endif
# ifndef BOOST_WEAK_PTR_HPP_INCLUDED
# include <boost/weak_ptr.hpp>
# endif
# ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
# include <boost/enable_shared_from_this.hpp>
# endif

_STLP_BEGIN_NAMESPACE

namespace tr1 {

using ::boost::bad_weak_ptr;
using ::boost::shared_ptr;
using ::boost::swap;
using ::boost::static_pointer_cast;
using ::boost::dynamic_pointer_cast;
using ::boost::const_pointer_cast;
using ::boost::get_deleter;
using ::boost::weak_ptr;
using ::boost::enable_shared_from_this;

// shared_ptr IO
// weak_ptr IO

} // namespace tr1

_STLP_END_NAMESPACE

#endif /* !_STLP_NO_EXTENSIONS && _STLP_USE_BOOST_SUPPORT */

#endif /* _STLP_MEMORY */

// Local Variables:
// mode:C++
// End:

Reece Dunn

unread,
Jul 21, 2013, 3:35:05 AM7/21/13
to andro...@googlegroups.com, nolo...@gmail.com
On Sunday, 21 July 2013 05:02:12 UTC+1, Jeffrey Walton wrote:
Hi All,

shared_ptr has been around since the TR1 days. When I try and use it,
I get the following: "error: 'std::shared_ptr' has not been declared"

The NDK version of STLport does not declare std::shared_ptr. It provides a version of std::tr1::shared_ptr, which is what you have noticed in the code.

What you can do is include a compatibility header which has the following code:

-----
namespace std
{
    typedef decltype(nullptr) nullptr_t;
}

#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>

namespace std
{
    using ::boost::shared_ptr;
    using ::boost::make_shared;
}
-----

NOTE: The nullptr_t defintion is needed for the current Boost headers. STLport does not define this either.

You may need to add other definitions, depending on what parts of the C++11 library you make use of.

- Reece

Jeffrey Walton

unread,
Jul 21, 2013, 4:01:42 AM7/21/13
to Reece Dunn, andro...@googlegroups.com
On Sun, Jul 21, 2013 at 3:35 AM, Reece Dunn <msc...@googlemail.com> wrote:
> On Sunday, 21 July 2013 05:02:12 UTC+1, Jeffrey Walton wrote:
>>
>> shared_ptr has been around since the TR1 days. When I try and use it,
>> I get the following: "error: 'std::shared_ptr' has not been declared"
>
> The NDK version of STLport does not declare std::shared_ptr. It provides a
> version of std::tr1::shared_ptr, which is what you have noticed in the code.
Interesting. I also failed with TR1:

arm-linux-androideabi-g++ -fpic -DESAPI_NO_ASSERT=1
-DESAPI_BUILD_TEST=1 -g2 -ggdb -O2 -Dprivate=public -Dprotected=public
-DSAFEINT_DISALLOW_UNSIGNED_NEGATION=1 -pipe -fsigned-char
-Woverloaded-virtual -Wreorder -Wconversion -Wmissing-declarations
-Wformat=2 -Wformat-security -Wuninitialized -Wno-unused
-fstrict-aliasing -fvisibility=hidden -fstack-protector-all
-Wstrict-overflow -Wall -Wextra -Wno-unused -Wno-type-limits
-Wtrampolines -std=c++0x -I. -I./esapi -I./deps
-I/opt/android-ndk-r8e//sources/cxx-stl/stlport/stlport/
--sysroot=/opt/android-ndk-r8e//platforms/android-14/arch-arm -c
src/EncoderConstants.cpp -o src/EncoderConstants.o
In file included from src/EncoderConstants.cpp:11:0:
./esapi/EsapiCommon.h:157:17: error: 'std::tr1::shared_ptr' has not
been declared

> What you can do is include a compatibility header which has the following
> code:
>
> -----
> namespace std
> {
> typedef decltype(nullptr) nullptr_t;
> }
>
> #include <boost/smart_ptr/shared_ptr.hpp>
> #include <boost/smart_ptr/make_shared.hpp>
>
> namespace std
> {
> using ::boost::shared_ptr;
> using ::boost::make_shared;
> }
> -----
>
> NOTE: The nullptr_t defintion is needed for the current Boost headers.
> STLport does not define this either.
>
> You may need to add other definitions, depending on what parts of the C++11
> library you make use of.

So I'm clear: I need to include Boost? (it does not appear to be in sysroot):

$ find /opt/android-ndk-r8e//sources/cxx-stl/stlport/stlport/ -iname boost
$

I prefer to avoid Boost because of the problems on some platforms
(some of the older Unix/Linux distros have problems, and its near
useless on Windows because of the way it configures itself (it
hardstops with a #pragma error)).

Also, I don't want to migrate to C++11 because it might cause
hardships with older platforms (the project is a few years old, and I
can't guarantee everyone has a C++11 compiler, or the C++11 compiler
works). I feel comfortable with TR1 since its been around for a decade
or so.

Would you happen to know if I will have the same problems with the
other STL library included in the NDK?

Anyway, I don't want to come off as argumentative. Thanks again.

Jeff

Reece Dunn

unread,
Jul 21, 2013, 4:36:06 AM7/21/13
to nolo...@gmail.com, andro...@googlegroups.com
On 21 July 2013 09:01, Jeffrey Walton <nolo...@gmail.com> wrote:
On Sun, Jul 21, 2013 at 3:35 AM, Reece Dunn <msc...@googlemail.com> wrote:
> On Sunday, 21 July 2013 05:02:12 UTC+1, Jeffrey Walton wrote:
>>
>> shared_ptr has been around since the TR1 days. When I try and use it,
>> I get the following: "error: 'std::shared_ptr' has not been declared"
>
> The NDK version of STLport does not declare std::shared_ptr. It provides a
> version of std::tr1::shared_ptr, which is what you have noticed in the code.
Interesting. I also failed with TR1:

STLport does not automatically add std::tr1::shared_ptr. If you look at the code, it is guarded with _STLP_USE_BOOST_SUPPORT, so you need to define that to make use of it (and have Boost in the include path).
 
So I'm clear: I need to include Boost? (it does not appear to be in sysroot):

Yes, you need to include Boost.

It is not provided with Android, you need to download Boost separately and point the include path to that directory.

I prefer to avoid Boost because of the problems on some platforms
(some of the older Unix/Linux distros have problems, and its near
useless on Windows because of the way it configures itself (it
hardstops with a #pragma error)).

You only need the Boost headers to get shared_ptr working. You don't need to build any of the libraries. You also need to point it to an explicitly downloaded version as Linux distros install it to /usr/include and you don't want to add an include to that path!
 
Also, I don't want to migrate to C++11 because it might cause
hardships with older platforms (the project is a few years old, and I
can't guarantee everyone has a C++11 compiler, or the C++11 compiler
works). I feel comfortable with TR1 since its been around for a decade
or so.

That's fine. then:
 1/  define _STLP_USE_BOOST_SUPPORT (-D_STLP_USE_BOOST_SUPPORT)
 2/  add an include path to Boost (e.g. -I/opt/boost/1.54)
 3/  use std::tr1::shared_ptr

I am using C++11, which should explain why Boost is requiring nullptr_t. If you are not, then the above steps should be adequate.

The reason I mentioned C++11 was because you were mentioning that std::shared_ptr was undefined and std::shared_ptr is a C++11 class.
 
Would you happen to know if I will have the same problems with the
other STL library included in the NDK?
 
I haven't had this problem with the GCC standard library provided with the NDK (gnustl_static/gnustl_shared). I am not sure about APP_STL := system.

Note that gnustl is licensed under the GPLv3 license, so if you use that library your program must comply with the GPLv3 license (i.e. provide the sources of your application to parties that request it).
 
Anyway, I don't want to come off as argumentative. Thanks again.

I don't see your questions as argumentative.

- Reece

Ray Donnelly

unread,
Jul 21, 2013, 5:10:17 AM7/21/13
to andro...@googlegroups.com

Sorry this is completely incorrect and dangerously so. Please read:
http://gcc.gnu.org/onlinedocs/libstdc++/faq.html
Or
http://gcc.gnu.org/onlinedocs/libstdc++/faq.html
.. in particular the bit " GCC RUNTIME LIBRARY EXCEPTION"

>>
>> Anyway, I don't want to come off as argumentative. Thanks again.
>
>
> I don't see your questions as argumentative.
>
> - Reece
>

> --
> You received this message because you are subscribed to the Google Groups "android-ndk" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
> To post to this group, send email to andro...@googlegroups.com.
> Visit this group at http://groups.google.com/group/android-ndk.
> For more options, visit https://groups.google.com/groups/opt_out.
>  
>  

Reece Dunn

unread,
Jul 21, 2013, 5:28:11 AM7/21/13
to andro...@googlegroups.com
So android-ndk/docs/CPLUSPLUS-SUPPORT.html is misleading:
-----
III.2. GNU libstdc++ license is GPLv3 + linking exception!
----------------------------------------------------------

Be aware that the GNU libstdc++ is covered by the GPLv3 license (and *not*
the LGPLv2 or LGPLv3 as some assume), full details available here:

    http://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html

Be sure that you comply with all clauses of this license.
-----

Ray Donnelly

unread,
Jul 21, 2013, 5:31:09 AM7/21/13
to andro...@googlegroups.com

Maybe it could be more clear if it's caused you to think closed source application development and gnu libstdc++ are incompatible.

Jeffrey Walton

unread,
Jul 23, 2013, 2:33:13 PM7/23/13
to Reece Dunn, andro...@googlegroups.com
Thanks Reece. I wanted to report back in case anyone else wanted a
perspective on this.

On Sun, Jul 21, 2013 at 4:36 AM, Reece Dunn <msc...@googlemail.com> wrote:
> On 21 July 2013 09:01, Jeffrey Walton <nolo...@gmail.com> wrote:
>>
>> ...
> STLport does not automatically add std::tr1::shared_ptr. If you look at the
> code, it is guarded with _STLP_USE_BOOST_SUPPORT, so you need to define that
> to make use of it (and have Boost in the include path).
OK. I don't want the full-blown Boost integration, so I did not define
_STLP_USE_BOOST_SUPPORT.

>> So I'm clear: I need to include Boost? (it does not appear to be in
>> sysroot):
> Yes, you need to include Boost.
Damn, that sucks.

I did a quick audit on some of the files included by the procedure
below, and Boost is still ignoring failures on critical paths. Silent
failures are one of my pet-peeves, so I'm probably going to have to
find an alternative to Boost.

N.B.: don't believe the fan boi's and their noise about Boost quality
and the QA process - its a myth. I filed bug reports on some of these
issues years ago - there is no reason for them to be present today.

> It is not provided with Android, you need to download Boost separately and
> point the include path to that directory.
The project has a deps/ directory for dependencies, so I stuffed a
partial Boost in there under boost-1.54.0. Here's what I did for the
partial Boost (picking out what I wanted).

Start by fetching the latest stable boost from svn. The TAR/ZIP
archives do not include Boost's tools, so you have to go to SVN.

$ svn co http://svn.boost.org/svn/boost/tags/release/Boost_1_54_0/
boost-1.54.0

Then, build bcp, which allows one to copy out a class with its dependencies:

$ cd boost-1.54.0
$ ./bootstrap.sh
$ cd tools/bcp
$ ../../bjam

Finally, copy out shared_ptr:

$ mkdir boost-shared_ptr
$ cd boost-1.54.0
$ ./dist/bin/bcp shared_ptr ../boost-shared_ptr

For shared_ptr and unordered_map, there were 2900+ files:

$ cd boost-stuff
$ find . -type f | wc -l
2929

>> ...
>> Also, I don't want to migrate to C++11 because it might cause
>> hardships with older platforms (the project is a few years old, and I
>> can't guarantee everyone has a C++11 compiler, or the C++11 compiler
>> works). I feel comfortable with TR1 since its been around for a decade
>> or so.
> That's fine. then:
> 1/ define _STLP_USE_BOOST_SUPPORT (-D_STLP_USE_BOOST_SUPPORT)
> 2/ add an include path to Boost (e.g. -I/opt/boost/1.54)
> 3/ use std::tr1::shared_ptr
Since I used Boost for shared_ptr and unordered_map, there was no
reason to define _STLP_USE_BOOST_SUPPORT - I used it directly.

> I am using C++11, which should explain why Boost is requiring nullptr_t. If
> you are not, then the above steps should be adequate.
The compiler did complain about nullptr_t. I needed to:

# define BOOST_NO_CXX11_NULLPTR 1

Unfortunately, there does *not* appear to be a macro to force Boost
into C++03 (http://www.boost.org/doc/libs/1_54_0/libs/config/doc/html/boost_config/boost_macro_reference.html).
Also, Boost does not honor '-sdt=c++03`.

Thanks again for your help.

Jeff
Reply all
Reply to author
Forward
0 new messages