Rationale for shared_ptr/array including both ptr to control and ptr to data in class

Hi, I was wondering why shared_ptr/array include both a ptr to the control block and a ptr to the data (ptr) in the class itself. I assume it's for performance reasons, but I didn't find anything about that in the docs. Greetings, Olaf

On 23.09.2011 13:43, Olaf van der Spek wrote:
Hi,
I was wondering why shared_ptr/array include both a ptr to the control block and a ptr to the data (ptr) in the class itself. I assume it's for performance reasons, but I didn't find anything about that in the docs.
It's for aliasing. You can have a shared_ptr that points to a subobject of the object controlled by the control block. Sebastian

On Fri, Sep 23, 2011 at 2:03 PM, Sebastian Redl <sebastian.redl@getdesigned.at> wrote:
I was wondering why shared_ptr/array include both a ptr to the control block and a ptr to the data (ptr) in the class itself. I assume it's for performance reasons, but I didn't find anything about that in the docs.
It's for aliasing. You can have a shared_ptr that points to a subobject of the object controlled by the control block.
Ah, of course. Does that apply to shared_array too? Olaf

Sebastian Redl wrote:
On 23.09.2011 13:43, Olaf van der Spek wrote:
Hi,
I was wondering why shared_ptr/array include both a ptr to the control block and a ptr to the data (ptr) in the class itself. I assume it's for performance reasons, but I didn't find anything about that in the docs.
It's for aliasing. You can have a shared_ptr that points to a subobject of the object controlled by the control block.
It's true that the separate pointer enables aliasing, but this is not the original reason for its existence. It supports pointer conversions (shared_ptr<T> converts to shared_ptr<U> when T* converts to U*.) shared_array doesn't technically need aliasing or conversions, its implementation just mirrors shared_ptr.

On Fri, Sep 23, 2011 at 4:18 PM, Peter Dimov <pdimov@pdimov.com> wrote:
It's true that the separate pointer enables aliasing, but this is not the original reason for its existence. It supports pointer conversions (shared_ptr<T> converts to shared_ptr<U> when T* converts to U*.)
shared_array doesn't technically need aliasing or conversions, its implementation just mirrors shared_ptr.
Ah. BTW, why doesn't shared_array provide size()? IMO it'd be quite useful to have.

On 24/09/2011 17:45, Olaf van der Spek wrote:
On Fri, Sep 23, 2011 at 4:18 PM, Peter Dimov<pdimov@pdimov.com> wrote:
It's true that the separate pointer enables aliasing, but this is not the original reason for its existence. It supports pointer conversions (shared_ptr<T> converts to shared_ptr<U> when T* converts to U*.)
shared_array doesn't technically need aliasing or conversions, its implementation just mirrors shared_ptr.
Ah. BTW, why doesn't shared_array provide size()? IMO it'd be quite useful to have.
Because it's not storing that information.

On 26/09/2011 14:42, Olaf van der Spek wrote:
On Mon, Sep 26, 2011 at 2:11 PM, Mathias Gaunard <mathias.gaunard@ens-lyon.org> wrote:
Ah. BTW, why doesn't shared_array provide size()? IMO it'd be quite useful to have.
Because it's not storing that information.
So why is it not storing that info?
Because it doesn't have it to begin with, and doesn't aim at having it. It's just a shared_ptr variant that calls delete[] instead of delete.

2011/9/26 Olaf van der Spek <ml@vdspek.org>
On Mon, Sep 26, 2011 at 2:11 PM, Mathias Gaunard <mathias.gaunard@ens-lyon.org> wrote:
Ah. BTW, why doesn't shared_array provide size()? IMO it'd be quite useful to have.
Because it's not storing that information.
So why is it not storing that info?
Because shared_array doesn't have it. Roman Perepelitsa.

Olaf van der Spek wrote:
Ah. BTW, why doesn't shared_array provide size()? IMO it'd be quite useful to have.
The obvious answer, that it doesn't have this information, has already been given, but it's not enough; you could legitimately ask why shared_array doesn't have it, that is, why its constructor doesn't take a size in addition to the pointer. The answer is, well, historical reasons. While the current shared_ptr allows you to easily implement a sized shared_array by storing the size in a deleter, when shared_array was first designed, this was not the case. shared_array was kept a simple reference-counted wrapper over new T[]. shared_ptr then evolved considerably, and shared_array has failed to keep up. So here we are. :-)

On Mon, Sep 26, 2011 at 3:20 PM, Peter Dimov <pdimov@pdimov.com> wrote:
Olaf van der Spek wrote:
Ah. BTW, why doesn't shared_array provide size()? IMO it'd be quite useful to have.
The obvious answer, that it doesn't have this information, has already been given, but it's not enough; you could legitimately ask why shared_array doesn't have it, that is, why its constructor doesn't take a size in addition to the pointer.
make_shared_array (not implemented yet) would also have the info.
The answer is, well, historical reasons. While the current shared_ptr allows you to easily implement a sized shared_array by storing the size in a deleter, when shared_array was first designed, this was not the case. shared_array was kept a simple reference-counted wrapper over new T[]. shared_ptr then evolved considerably, and shared_array has failed to keep up. So here we are. :-)
So, could 'this' be 'fixed'? ;) Not having size() and others like begin, end, etc, is a serious drawback IMO. P;af

From: Olaf van der Spek Not having size() and others like begin, end, etc, is a serious drawback IMO.
Then why not simply use either shared_ptr<array<T, N>> or shared_ptr<vector<T>>? Best regards, Robert

From: Olaf van der Spek Not having size() and others like begin, end, etc, is a serious drawback IMO.
Then why not simply use either shared_ptr<array<T, N>> or shared_ptr<vector<T>>?
Best regards, Robert
shared_ptr<array<T, N>> limits you to cases where you know the size of the array at compile time shared_ptr<vector<T>> results in two dynamic allocations: one for the vector object itself, and one for its internal array Regards, Nate

On Tue, Sep 27, 2011 at 4:26 AM, Nathan Ridge <zeratul976@hotmail.com> wrote:
From: Olaf van der Spek Not having size() and others like begin, end, etc, is a serious drawback IMO.
Then why not simply use either shared_ptr<array<T, N>> or shared_ptr<vector<T>>?
Best regards, Robert
shared_ptr<array<T, N>> limits you to cases where you know the size of the array at compile time
shared_ptr<vector<T>> results in two dynamic allocations: one for the vector object itself, and one for its internal array
It'll also initialize the elements (not wanted) and it provides another interface. Olaf
participants (7)
-
Mathias Gaunard
-
Nathan Ridge
-
Olaf van der Spek
-
Peter Dimov
-
Robert Kawulak
-
Roman Perepelitsa
-
Sebastian Redl