What are the differences between VS2010's std::shared_ptr and boost::shared_ptr?
Are the implementations almost the same? Or are there significant differences?
What is the most efficient/optimized?
Thanks.
VS2010's shared_ptr is implementation conforming (or, at least, trying to conform) C++11 standard.
boost::shared_ptr on the other hand, was developed way earlier, and as part of boost rather than C++ standard library. I believe both are efficient enough for production use, but using boost forces you to... use boost ;). Which in some cases is quite unacceptable.
Related
For a software I have to avoid any use of memory in the heap, and only rely on stack-allocated memory. Then, this prevents me from using any C++ standard containers, such as vector, map, string (well, basic_string), which I would really like to use, to ease development and data manipulation.
I found (many) implementations of stack allocators, such as this one which itself references two others, or this one from chromium.
Many of them are not fully compliant with the standard, or rely on C++11 (and I am stuck with C++03 at the moment, sadly). Do you have any feedback about a good already existing stack allocator for C++03 or should I adapt one of the above?
Thanks!
Howard Hinnant's short_alloc.h (see also here) is a pretty good start (you will need to add C++03 boilerplate, see here).
Of course, this will still go to the heap if it runs out of memory, the alternative is to throw std::bad_alloc.
We've just upgraded our compiler to VC++ 2013 which has support for C++ 11. Previously we've been using shared_ptr and scoped_ptr classes from Boost, but since that is all we've been using from Boost, we're looking to remove that dependency.
As far as I can tell, std::shared_ptrs are a drop-in replacement for boost::shared_ptrs, so that's (hopefully) easy.
However, what is the best replacement for Boost scoped_ptrs (if there is one)? Would it be unique_ptr?
(To be honest, even though I wrote the code, it was about 10 years ago, and I've forgotten what the purpose of using scoped_ptrs was... Maybe I was just "playing" with Boost, but as far as I can see a plain pointer would probably do in the cases I've examined).
Yes, scoped_ptr can and should be replaced with unique_ptr. They represent the same idea (unique ownership), but unique_ptr does it better, and allows transfer of ownership via move semantics. (scoped_ptr didn't because it wasn't possible in C++98)
The background is in this question of mine. Put shortly, I have to fork in a multithreaded C++ program, so I'd like to figure out how much I can do when restricted to reentrant functions only, and one of the most essential things is dynamic memory.
So, malloc is known to be non-reentrant. But what about C++'s new? I googled for that with not many relevant results (mostly due to the difficulty to hit the correct "new"), but there is at least one claim that new is reentrant. There is also a relevant question concerning the whole C++ standard library with no satisfying answer.
Edit: I guess the standard didn't say anything about this, so I'm mostly concerned about major implementations.
I've looked at both the gcc libsupc++ and clang libc++ source, for replacing the standard-conforming C++ new/delete operators - to support native SIMD alignment requirements on platforms where it wasn't guaranteed by malloc.
They are basically wrappers for malloc and free with some EH logic, etc. I am not a language lawyer, but unless both have it wrong, I think it's safe to conclude: no, they are not reentrant.
Standard allows new to be just a wrapper around malloc, so if malloc can be not reentrant, so can new.
Thread-safety and re-entrance are not exactly the same.
AFAIK, the C++ ISO standard does not guarantee thread-safety for new and delete operators. But g++ implementation does provide thread-safetly (and it's one of the reasons it's slow).
Boost is essentially a c++03 library (which stimulated the c++11 standard). I'm contemplating of using some boost libraries (those that are not implemented in c++11). If I'm using c++11, does boost compile (there may be issues with non-copyable but movable objects)? and how well is boost making use of the c++11 features (variadic templates are an obvious thing to use [by some boost libraries] instead of much of the boost MPL)? (I couldn't find this amongst the boost FAQ).
Boost is moving towards using C++11 features.
But one thing to remember is that boost is not "a library", but rather a collection of libraries. Some of them (for example boost::array) probably won't ever be updated to use many c++11 features. Why should it, when you have std::array in the standard (which was based on boost::array?)
On the other hand, Boost would like to remain useful for people who are still using C++03.
Note: Even though I write as if "Boost" is some monolithic entity, there are lots of people who contribute to boost and they have many different opinions. ;-)
To see how well various boost libraries work with C++11 compilers, you can check out the Boost Testing web page.
C++11 was made do be as backwards compatible as possible. Unless boost is using reserved keywords that are new to C++11, there is no reason I know of why it shouldn't compile just fine with the new standard.
I would like to enable support for C++0x in GCC with -std=c++0x. I don't absolutely necessarily need any of the currently supported C++11 features in GCC 4.5 (and soon 4.6), but I would like to start getting used to them. For example, in a few places where I use iterators, an auto type would be useful.
But again, I don't need any of the currently supported features. The goal here is to encourage me to incorporate the features of the new standard into my programming "vocabulary".
From what you know of the C++11 support, is it a good idea to enable it in GCC, and then embrace it by, for example, switching from using boost::shared_ptr to std::shared_ptr exclusively as the two don't mix?
PS: I'm aware of this good question which compares the different flavors of shared_ptr but I'm asking a higher level advice on which to use before the standard is finalized. Another way of putting that is, when a compiler like GCC says it supports an "experimental feature", does that mean I am likely to encounter weird errors during compilation that will be major time sinks and a source of cryptic questions on StackOverflow?
Edit: I decided to switch back from std::shared_ptr because I just don't trust its support in GCC 4.5 as shown by example in this question.
There are a couple of reasons to switch over to std::shared_ptr:
You remove a dependency on Boost.
Debuggers. Depending on your compiler and debugger, the debugger may be "smart" about std::shared_ptr and show the pointed to object directly, where it wouldn't for say, boost's implementation. At least in Visual Studio, std::shared_ptr looks like a plain pointer in the debugger, while boost::shared_ptr exposes a bunch of boost's innards.
Other new features defined in your linked question.
You get an implementation which is almost guaranteed to be move-semantics enabled, which might save a few refcount modifications. (Theoretically -- I've not tested this myself) As of 2014-07-22 at least, boost::shared_ptr understands move semantics.
std::shared_ptr correctly uses delete [] on array types, while boost::shared_ptr causes undefined behavior in such cases (you must use shared_array or a custom deleter) (Actually I stand corrected. See this -- the specialization for this is for unique_ptr only, not shared_ptr.)
And one major glaring reason not to:
You'd be limiting yourself to C++11 compiler and standard library implementations.
Finally, you don't really have to choose. (And if you're targeting a specific compiler series (e.g. MSVC and GCC), you could easily extend this to use std::tr1::shared_ptr when available. Unfortunately there doesn't seem to be a standard way to detect TR1 support)
#if __cplusplus > 199711L
#include <memory>
namespace MyProject
{
using std::shared_ptr;
}
#else
#include <boost/shared_ptr.hpp>
namespace MyProject
{
using boost::shared_ptr;
}
#endif
I suppose it depends how much you use boost. I personally only use it very sparingly (in fact the random number library, in a single project). I've recently started using -std=c++0x for my other projects, and I use the new std:: library features like shared_ptr in them. I like my projects to have the minimum of dependencies, so I'd rather be dependent on the compiler's standard library implementation than on boost.
But I don't think there is a one-size-fits-all answer to this question.
You should always use std::shared_ptr wherever possible, if it's available, instead of boost. This is basically because all new interfaces which use shared_ptr will use the Standard shared ptr.
It's probably not a bad idea to start getting into the habit of using std::shared_ptr when allowed by the compiler. Since the interface is the same as boost's shared_ptr you can always switch back if you needed to.
If you are just building on the one platform that is fine (make the switch)
(Note: You do have unit tests to validate backward compatibility don't you?)
If you compile on multiple platforms is where it becomes a little more awkward as you need to validate that the features on g++ 4.5 are available on all the platforms you use (ie building for MAC/Linux the default Mac g++ compiler is still a couple of version's behind the default compilers on Linux).
Another reason to switch over to std::shared_ptr:
it supports std::unique_ptr, i.e. has constructor.
boost::shared_ptr doesn't.
Aside from implementation consistency, boost::shared_ptr currently retains at least two niche advantages over std::shared_ptr:
The availability of boost::make_shared_noinit. It's particularly useful in conjunction with arrays, avoiding both the cost of zero-initialization and the overhead of separate allocation. (FWIW, it's also a proposed addition to the standard.)
Boost.Python makes special use of boost::shared_ptr's support for type-erased custom deleters, but doesn't yet do the same for std::shared_ptr.
I found std::shared_ptr to be faster than boost::shared_ptr. I did a test, you can review the code and see the pie chart results comparing boost, Qt, and std shared pointers.
https://www.osletek.com...