93

C++14 presents std::dynarray:

std::dynarray is a sequence container that encapsulates arrays with a size that is fixed at construction and does not change throughout the lifetime of the object.

std::dynarray must be allocated in run-time as same as std::vector.

So what are the benefits and the usage of std::dynarray while we can use std::vector which is more dynamic (and also re-sizable)?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
masoud
  • 55,379
  • 16
  • 141
  • 208
  • 1
    Hey, since when is "C++14" a tag? I was looking for that the other day and it didn't exist... – Kerrek SB Oct 01 '13 at 08:12
  • 1
    Is `std::valarray` renamed as `std::dynarray`? Whats dynamic about `std::dynarray` when it cannot be re-sized? – yasouser Oct 01 '13 at 08:25
  • 9
    @yasouser, no, it's nothing to do with `valarray`. It's dynamic because the length of the array is a run-time value, it doesn't need to be known at compile-time, unlike `std::array` – Jonathan Wakely Oct 01 '13 at 08:28
  • Edited tag to C++1y as that is the used tag over SO until the standard is actually there. – KillianDS Oct 01 '13 at 09:12
  • 23
    Note that at the C++ Standards Committee meeting last week, `dynarray` was removed from C++14 and put into a future Technical Specification (think of that as a new version of TR1) because it has some serious technical problems. – Pete Becker Oct 01 '13 at 10:02
  • @PeteBecker: Great to hear that, as the current version of `dynarray` seems to be a bad idea… – MFH Oct 01 '13 at 12:28
  • @MFH: Why do you think it's a bad idea? – masoud Oct 01 '13 at 13:24
  • 2
    @MM.: first of all: there currently seems to be no implementation - which is an extremely bad sign and the standards committee learned the hard way not to specify features that are not well tested (e.g. export, dynamic exception specification,…) second: the fact that `dynarray` allocates on the stack leads to several potential new pitfalls (e.g. running out of stack space) all leading to undefined behavior and in addition to that prevents optimizations like move semantics… To me this seems like a hidden behind a STL-like layer VLA, which was not adopted in C++ for good reasons. – MFH Oct 01 '13 at 18:02
  • Was `dynarray` _required_ to be able to use stack allocation since its first proposal, or was it something added afterwards? As soon as I heard about the concept of a dynarray I started using a trivial implementation (one of those "why didn't C++ already have this?" cases) but this is the first I hear it was required to be able to do allocation by means beyond just calling `operator new` (that simplicity was one of the strongest points IMO). – Luis Machuca Nov 28 '13 at 00:58
  • 2
    @LuisMachuca: Very, very, very late reply: `dynarray` was expected to do stack-allocation whenever possible (if supported by the compiler + library) and use heap allocation (`new[]`) only as fallback if that was not possible… (e.g. when not supported or not applicable) – MFH Oct 30 '14 at 08:25
  • 3
    [dynarray](http://en.cppreference.com/w/cpp/container/dynarray) is no longer a part of the draft C++14 – cassinaj Feb 26 '15 at 12:53
  • 1
    @deepmax I suggest you to remove the C++14 tag and edit your question according to the fact that dynarray is **NOT** part of C++14. – jotik Apr 21 '16 at 10:25

2 Answers2

100

So what are the benefits and the usage of std::dynarray, when we can use std::vector which is more dynamic (Re-sizable)?

dynarray is smaller and simpler than vector, because it doesn't need to manage separate size and capacity values, and it doesn't need to store an allocator.

However the main performance benefit is intended to come from the fact that implementations are encouraged to allocate dynarray on the stack when possible, avoiding any heap allocation. e.g.

std::dynarray<int> d(5);   // can use stack memory for elements
auto p = new std::dynarray<int>(6);  // must use heap memory for elements

This optimisation requires cooperation from the compiler, it can't be implemented as a pure library type, and the necessary compiler magic has not been implemented and noone is sure how easy it is to do. Because of the lack of implementation experience, at the C++ committee meeting in Chicago last week it was decided to pull std::dynarray from C++14 and to issue a separate array extensions TS (technical specification) document defining std::experimental::dynarray and arrays of runtime bound (ARBs, similar to C99 VLAs.) This means std::dynarray will almost certainly not be in C++14.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • 1
    Great, I was wondering if there were *any* non-trivial implementations of `dynarray` in the wild. I always thought you need two independent implementations of existing practice before something becomes eligible for standardization. – Kerrek SB Oct 01 '13 at 09:08
  • No, there are no known implementations of a stack-allocating `dynarray`. Although implementation experience is very useful, there is no set rule requiring it (but some would say there should be!) – Jonathan Wakely Oct 01 '13 at 09:14
  • just brainstorming here but what about creating 2 functions: std::dynarray make_dyn_autostorage(int) and std::dynarray make_dyn_heap(int)? – Serve Laurijssen Oct 01 '13 at 10:28
  • @ServéLaurijssen: I think once you return such an object from a function, you don't have a choice about the implementation anymore. At best the compiler can detect when you're using a dynamic array in a purely local setting and with small enough size to fit it on the stack. – Kerrek SB Oct 01 '13 at 10:30
  • @ServéLaurijssen, that doesn't help: how do you make a `std::dynarray` allocate on the stack? Who reserves the stack space? You still need compiler magic. – Jonathan Wakely Oct 01 '13 at 11:06
  • Hang on, are you saying that ARBs are also not going to be in the next standard? – Kerrek SB Oct 01 '13 at 11:56
  • 2
    @KerrekSB, yes, library motion 10 in Chicago was: "Move we create a Working Paper for a planned Array Extensions TS, remove the edits applied to the C++14 CD by the two papers [N3639](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html), "Runtime-sized arrays with automatic storage duration (revision 5)" [N3662](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3662.html), "C++ Dynamic Arrays (dynarray)" and direct the Array Extensions TS project editor to apply those words to the Array Extensions Working Paper as its initial content." – Jonathan Wakely Oct 01 '13 at 12:22
  • There were some strong feelings that the two proposals are coupled and should not be standardised separately, and also improving the ARB feature might make it easier to implement `dynarray` – Jonathan Wakely Oct 01 '13 at 12:23
  • I don't understand why a stack allocator wouldn't perform well instead of std::dynarray full implementation, modulo the state that must be kept. Why a compiler needs optimizations here? – Germán Diago Aug 22 '14 at 07:38
  • I love the way the C++ guys name they spec: Technical Report 1; Technical Specification ... Sounds both primitive and advanced. – h9uest Feb 06 '15 at 11:01
  • 4
    @h9uest that is nothing to do with "the C++ guys", those are the official names for the deliverables of an [ISO](http://www.iso.org/) technical committee, see http://www.iso.org/iso/home/standards_development/deliverables-all.htm?type=ts and http://www.iso.org/iso/home/standards_development/deliverables-all.htm?type=tr – Jonathan Wakely Feb 07 '15 at 04:08
31

As you said yourself, std::dynarray is for a fixed-size dynamic array. It is not resizable. It's roughly speaking an improvement over new T[N] and over std::unique_ptr<T[]>(new T[N]).

Not needing to resize or manage capacity means you can implement the data structure with less complexity and in less space.

Moreover, std::dynarray is a weird animal that allows the implementation to implement it in different, non-specific ways, e.g. it's possible to put the array on the stack. Calling an allocation function is "optional". You can specify an allocator to construct the elements of the array, but that is not part of the type.

You might also wonder why we need std::dynarray and variable-length arrays. VLAs in C++14 are much more restrictive; they can only be local, automatic variables and offer no way to specify an allocation policy, and of course they don't have a standard container interface.


Some examples from 23.3.4.2 of a "current draft" (take that, Google cache):

explicit dynarray(size_type c);

Effects: Allocates storage for c elements. May or may not invoke the global operator new.

template <class Alloc>
dynarray(size_type c, const Alloc& alloc);

Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction.

Whether or not you can use a given allocator to construct the array elements is a global trait:

template struct uses_allocator, Alloc> : true_type { };

Requires: Alloc shall be an Allocator (17.6.3.5). [Note: Specialization of this trait informs other library components that dynarray can be constructed with an allocator, even though it does not have a nested allocator_type.]

Edit: Jonathan Wakely's answer is bound to be far more authoritative and insightful.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Passing an allocator to `dynarray`'s constructor is never used for allocation, it's only used as an argument to the elements' constructors (using "uses-allocator construction"). That's why you can't query if the allocator was used: because it never is. – Jonathan Wakely Oct 01 '13 at 08:34