Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Different syntax for shared arrays between unique_ptr and shared_ptr

331 views
Skip to first unread message

Edward Diener

unread,
Apr 15, 2012, 2:29:47 AM4/15/12
to
As I understand it specifying a non-shared array with unique_ptr is
done using the syntax:

std::unique_ptr<T[]> up(new T[n]);

The unique_ptr has a partial specialization to handle this.

The syntax for handling shared arrays with shared_ptr is different:

std::shared_ptr<T> sp(new T[n],std::default_delete<T[]>());

Why is the syntax for working with arrays in unique_ptr and shared_ptr
different ?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

SG

unread,
Apr 15, 2012, 3:37:29 PM4/15/12
to
On 15 Apr., 08:29, Edward Diener wrote:
> As I understand it specifying a non-shared array with unique_ptr is
> done using the syntax:
>
> std::unique_ptr<T[]> up(new T[n]);
>
> The unique_ptr has a partial specialization to handle this.
>
> The syntax for handling shared arrays with shared_ptr is different:
>
> std::shared_ptr<T> sp(new T[n],std::default_delete<T[]>());
>
> Why is the syntax for working with arrays in unique_ptr and shared_ptr
> different ?

The short and easy answer: because nobody proposed to add a T[]
specialization to shared_ptr (not to my knowledge).

I just want to point out that shared_ptr needs more book keeping
(reference counter). So, you'd have two allocated memory blocks, the
ref counter and the array itself. This memory layout is very similar
to the layout you get by writing

auto sv = make_shared<vector<T>>(n);

on any decent implementation that would allocate the sizeof(vector<T>)
bytes together with the ref counting book keeping bits. You're just
getting an an additional level of indirection if you access vector
elements via sv. Though, You can avoid this using the vector's
iterators for a loop. So, what I'm saying is that I see little reason
to prefer sharedptr<T> with an array deleter over a
shared_ptr<vector<T>>.

Cheers!
SG

Daniel Krügler

unread,
Apr 15, 2012, 3:42:13 PM4/15/12
to
Am 15.04.2012 08:29, schrieb Edward Diener:
> As I understand it specifying a non-shared array with unique_ptr is
> done using the syntax:
>
> std::unique_ptr<T[]> up(new T[n]);
>
> The unique_ptr has a partial specialization to handle this.

This is so, because std::unique_ptr is supposed to be the direct
replacement for std::auto_ptr or a naked pointer and there should be
near to zero runtime drawback when used in stateless standard form (no
deleter or just an empty, stateless deleter). This means, basically all
aspects are determined during compile-time. Because of this it seemed
natural to also add a specialization for arrays, because such a
specialization also has to take care for subtle gotchas related to
conversions (Arrays are not polymorphic).

> The syntax for handling shared arrays with shared_ptr is different:
>
> std::shared_ptr<T> sp(new T[n],std::default_delete<T[]>());

The emphasis of std::shared_ptr was heavily inspired by dynamic
(runtime) properties, especially it was considered important that
instances of such types can be exchanged between dynamic libraries (Even
though not "de jure" regulated by the standard, it is a de facto
reality). This mean that type-erasing the deleter was a natural design
decision.

> Why is the syntax for working with arrays in unique_ptr and shared_ptr
> different ?

There was indeed a related request by US comment 105, see

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3289.pdf

and here:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US105

The request was rejected, because no clear consensus could be found:

"There is no consensus to adopt this change"

This means that even though some arguments where brought up that
demonstrate the inconsistency the arguments were not overwhelming
convincing at that point.

HTH & Greetings from Bremen,

Daniel Krügler

Edward Diener

unread,
Apr 15, 2012, 9:20:16 PM4/15/12
to
I agree that using std::vector instead of C-style arrays is my preferred
way of working. Nonetheless if C-style arrays were supported with both
std::unique_ptr and std::shared_ptr it would seem beneficial to use the
same syntax for both. Evidently that never happened.

Edward Diener

unread,
Apr 15, 2012, 9:20:51 PM4/15/12
to
On 4/15/2012 3:42 PM, Daniel Krügler wrote:
> Am 15.04.2012 08:29, schrieb Edward Diener:
>> As I understand it specifying a non-shared array with unique_ptr is
>> done using the syntax:
>>
>> std::unique_ptr<T[]> up(new T[n]);
>>
>> The unique_ptr has a partial specialization to handle this.
>
> This is so, because std::unique_ptr is supposed to be the direct
> replacement for std::auto_ptr or a naked pointer and there should be
> near to zero runtime drawback when used in stateless standard form (no
> deleter or just an empty, stateless deleter).

There has to be some deleter. It may not use any memory, but it still
has to exist or memory never gets freed.

> This means, basically all
> aspects are determined during compile-time. Because of this it seemed
> natural to also add a specialization for arrays, because such a
> specialization also has to take care for subtle gotchas related to
> conversions (Arrays are not polymorphic).
>
>> The syntax for handling shared arrays with shared_ptr is different:
>>
>> std::shared_ptr<T> sp(new T[n],std::default_delete<T[]>());
>
> The emphasis of std::shared_ptr was heavily inspired by dynamic
> (runtime) properties, especially it was considered important that
> instances of such types can be exchanged between dynamic libraries (Even
> though not "de jure" regulated by the standard, it is a de facto
> reality). This mean that type-erasing the deleter was a natural design
> decision.

I can understand that shared_ptr has to be passed between modules
successfully. But I do not understand why this impacts the syntax for
using it with C-style arrays.

>
>> Why is the syntax for working with arrays in unique_ptr and shared_ptr
>> different ?
>
> There was indeed a related request by US comment 105, see
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3289.pdf
>
> and here:
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3296.html#US105

Glad to see others noticed what I noticed.

>
> The request was rejected, because no clear consensus could be found:
>
> "There is no consensus to adopt this change"
>
> This means that even though some arguments where brought up that
> demonstrate the inconsistency the arguments were not overwhelming
> convincing at that point.

This seems to be a non-technical decision based on unwillingness to
consider the disparate syntaxes as a deficiency. Technically of course
syntactical differences on similar concepts is not a deficiency in the
sense that one can not achieve one's goal wih a different syntax. But
consistency makes up a very large part of computer language usage and I
do not think it was achieved in this case.
0 new messages