This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.

### 740. Please remove `*_ptr<T[N]>`

Section: 20.3.1 [unique.ptr] Status: CD1 Submitter: Herb Sutter Opened: 2007-10-04 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [unique.ptr].

View all issues with CD1 status.

Discussion:

Please don't provide `*_ptr<T[N]>`. It doesn't enable any useful bounds-checking (e.g., you could imagine that doing `op++` on a `shared_ptr<T[N]>` yields a `shared_ptr<T[N-1]>`, but that promising path immediately falters on `op--` which can't reliably dereference because we don't know the lower bound). Also, most buffers you'd want to point to don't have a compile-time known size.

To enable any bounds-checking would require run-time information, with the usual triplet: base (lower bound), current offset, and max offset (upper bound). And I can sympathize with the point of view that you wouldn't want to require this on `*_ptr` itself. But please let's not follow the `<T[N]>` path, especially not with additional functions to query the bounds etc., because this sets wrong user expectations by embarking on a path that doesn't go all the way to bounds checking as it seems to imply.

If bounds checking is desired, consider a `checked_*_ptr` instead (e.g., `checked_shared_ptr`). And make the interfaces otherwise identical so that user code could easily `#define/typedef` between prepending `checked_` on debug builds and not doing so on release builds (for example).

Note that some may object that `checked_*_ptr` may seem to make the smart pointer more like `vector`, and we don't want two ways to spell `vector`. I don't agree, but if that were true that would be another reason to remove `*_ptr<T[N]>` which equally makes the smart pointer more like `std::array.` :-)

[ Bellevue: ]

> Suggestion that fixed-size array instantiations are going to fail at compile time anyway (if we remove specialization) due to pointer decay, at least that appears to be result from available compilers.

> So concerns about about requiring static_assert seem unfounded.

> After a little more experimentation with compiler, it appears that fixed size arrays would only work at all if we supply these explicit specialization. So removing them appears less breaking than originally thought.

> straw poll unanimous move to Ready.

Proposed resolution:

Change the synopsis under 20.3.1 [unique.ptr] p2:

>     ...
>     template<class T> struct default_delete;
>     template<class T> struct default_delete<T[]>;
>     template<class T, size_t N> struct default_delete<T[N]>;

>     template<class T, class D = default_delete<T>> class unique_ptr;
>     template<class T, class D> class unique_ptr<T[], D>;
>     template<class T, class D, size_t N> class unique_ptr<T[N], D>;
>     ...

Remove the entire section [unique.ptr.dltr.dflt2] `default_delete<T[N]>`.

Remove the entire section [unique.ptr.compiletime] `unique_ptr` for array objects with a compile time length and its subsections: [unique.ptr.compiletime.dtor], [unique.ptr.compiletime.observers], [unique.ptr.compiletime.modifiers].