[GSoC] Update on extend shared_ptr to support array

Fan You youfan.noey@gmail.com
Wed Mar 25 15:13:00 GMT 2015


>2015-03-24 8:54 GMT-04:00 Jonathan Wakely <jwakely@redhat.com>:
> Have you submitted a formal GSoC proposal to Melange yet?  I have just
> renewed my Melange account and applied to be a mentor again, so I
> can't see the proposals until that is approved.

Yes, I've already submitted it.

> There's an issue I'd forgotten about which we should probably address:
>
> In C++11 today, it is already possible to use std::shared_ptr<T[N]>,
> although it's hard to use correctly and almost useless. For example,
> this is valid in C++11:
>
>  #include <memory>
>
>  int main()
>  {
>    int array[3];
>    std::shared_ptr<int[3]> p(&array, [](void*){});
>  }
>
> Although it's hard to use, this is technically valid and has clearly
> defined semantics, which are different from
> std::experimental::shared_ptr<int[3]>. In particular,
> std::shared_ptr<int[3]>::element_type is int[3] but
> std::experimental::shared_ptr<int[3]>::element_type is int.
>
> (I'm not sure if a non-empty std::shared_ptr<T[]>, i.e. array of
> unknown bound, can be used in C++11, so that might be even more
> useless).
>
> So while you're implementing the new semantics, we need to decide if
> we want to continue supporting the old semantics (which are
> technically required for C++11 conformance, but it's possible no-one
> cares about that.)
>
> I hope I've explained that clearly, let me know if I didn't.

It's pretty clear, thanks :)

>
> I advised you to add a specialization of std::__shared_ptr<T[]>, so
> that std::experimental::shared_ptr<T[]> would be simple to write and
> most of the implementation would be in the __shared_ptr
> specialization. That makes it impossible to support the old C++11
> semantics, so it might not be the right approach (sorry!)
>
> I can see at least three options:
>
> (1) Ignore the C++11 requirements and just make __shared_ptr<T[]> and
>    __shared_ptr<T[N]> meet the Fundamentals TS requirements. This
>    would be the simplest option, but is not strictly conforming and
>    carries some risk (C++17 might specify std::shared_ptr<T[]>
>    differently from std::experimental::shared_ptr<T[]> and we'd have
>    to change it again).

I don't know how much risk would C++17 put on this. But right, it's the
simplest solution for now.

>
> (2) Do not change __shared_ptr. Implement experimental::shared_ptr<T>
>    by simply deriving from __shared_ptr<T>. Implement the array
>    specializations experimental::shared_ptr<T[N]> and
>    experimental::shared_ptr<T[]> by re-implementing them completely,
>    without using __shared_ptr. That is quite a lot of work, and code
>    duplication (you would need to write all the comparison operators
>    again for the specializations).

This is my first idea and its the "safest" one, I guess. However,
In my first working sample, I also find that it will cause a lot duplications,
which is unnecessary. So, this may not be a good option.

>
> (3) Add a specialization for __shared_ptr<__libfund_v1<T>> where
>    __libfund_v1 is just a simple tag type like:
>
>    template<typename _Tp>
>      struct __libfund_v1 { using type = _Tp; };
>
>    The __shared_ptr<__libfund_v1<>> specialization would implement
>    the Fundamentals TS semantics, i.e. array support, then make
>    experimental::shared_ptr<T[N]> derive from
>    __shared_ptr<__libfund_v1<T[N]>> so it uses the specialization.
>    This would allow us to isolate the different semantics required by
>    the Library Fundamentals TS in the new specialization, not
>    changing the behaviour of the C++11 shared_ptr template.
>
>    We could also add the following alias template to allow people to
>    use the new specialization directly (for people who want to use
>    __shared_ptr<T[], LP> with a non-default lock policy):
>
>    namespace std { namespace experimental {
>      template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
>        using __shared_ptr = std::__shared_ptr<__libfund_v1<_Tp>, _Lp>;
>    } }
>
>
> Any other suggestions?
>
> I think it would be good to discuss this (and maybe experiment with
> the different options) before doing too much more work that might go
> in a wrong direction.
>

The third one could be a good option. This one didn't actually add too much
complexity on the first option. I can start doing some experiments on it.

I have no other suggestion for now, maybe I will come up with some
during the experiment.



More information about the Libstdc++ mailing list