45

Draft C++14 includes both runtime-sized arrays and the std::dynarray container. From what I can tell, the only real difference between the two is that std::dynarray has an STL interface (e.g., begin, end, size, etc.), while runtime-sized arrays do not. So why does C++14 need them both?

I understand that runtime-sized arrays are part of the core language, while std::dynarray is part of the standard library, but the proposal for std::dynarray makes clear that the authors expect compilers, in many cases, to offer special support for std::dynarray so that it can be as efficient as possible, i.e., as efficient as a runtime-sized array. As such, the language/library distinction seems somewhat artificial.

So, again, why does C++14 need both runtime-sized arrays and std::dynarray? And given that std::dynarray has a richer (STLified) interface, why not just drop runtime-sized arrays, assuming that std::dynarray can be implemented with equal runtime efficiency?

Clarification

When I talk about "runtime-sized arrays," I'm referring to a new C++14 core language feature that's described in N3639, not to traditional C arrays or VLAs or anything in C++11.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
KnowItAllWannabe
  • 12,972
  • 8
  • 50
  • 91
  • 1
    What are you comparing dyn array to – aaronman Jun 27 '13 at 21:56
  • 2
    To runtime-sized arrays (described [here](http://isocpp.org/files/papers/N3639.html).) – KnowItAllWannabe Jun 27 '13 at 21:59
  • by "runtime-sized arrays", do you mean `std::vector`? If so, the difference is mainly that with `std::dynarray` you *ensure* that there will be no resize (and therefore reallocations) during the life that object; therefore you can have stronger guaranties on the memory used by the `dynarray` that you can't with `vector`. – alfC Jun 27 '13 at 22:01
  • @KnowItAllWannabe, ah, I see now what you mean by "runtime-sized arrays". Yes, to me the only difference is that one is a STL container and the other is not, (which is not a small thing). The same can be said about the `std::array` vs. C-static-arrays. – alfC Jun 27 '13 at 22:05
  • 1
    You almost have something like dynarrays already with `std::unique_ptr`, but that one lacks iterators. That said, the difference is not very big. Variable-length arrays on the other hand are something completely different. – Kerrek SB Jun 27 '13 at 22:13
  • 2
    C added VLAs (variable length arrays) in C99. C11 made them optional. In both C99 and C11, there's no mechanism for detecting stack overflow when creating a VLA; if the array is too big the behavior is undefined. – Keith Thompson Jun 27 '13 at 22:50
  • 1
    [Stroustrup's comment](http://www.stroustrup.com/C++11FAQ.html#C99) about *not* adding C99-style VLAs to C++11 is interesting: "***Not*** VLAs (Variable Length Arrays; thank heaven for small mercies)." – Keith Thompson Jun 27 '13 at 22:52
  • 1
    That's like asking why we don't just ditch potatoes because we have crisps. The `dynarray` class will probably use runtime-sized arrays (when feasible). – RamblingMad Feb 03 '14 at 08:58
  • 2
    For anyone who may find this, `std::dynarray` was removed from the C++14 standard. See comment `CH 2` [In the official status](https://isocpp.org/files/papers/n3852.html). If you need this functionality, please use Boost. – Warpspace Dec 01 '16 at 04:32

3 Answers3

32

N3639 proposes to add local runtime-sized arrays with automatic storage duration to C++.

N2648 says that in keeping with C++ practice, std::dynarrays are usable with more than just automatic variables. But to take advantage of the efficiency stack allocation, we wish to make dynarray optimizable when used as an automatic variable.

In short, C11 style runtime-sized arrays are restricted to being stored on the stack. dynarray is not, but can be optimized when stored on the stack to be as efficient as C11 style runtime-sized arrays (or so is the goal).

C11 style runtime-sized arrays can be a useful syntax still, and the cost to increase intercompilability with C isn't high: the mechanism would have to be implemented for efficient automatic dynarray anyhow. In addition, C11 style runtime-sized arrays are first class citizens, and exist regardless of use of std libraries by the programmer.

There are important differences between actual C11 runtime-sized arrays and C++1y C11-style runtime-sized arrays, not the least of which is the runtime sizeof that actual C11 runtime-sized arrays support. But basic use of it may be compatible.

Note that in the end, neither where added in C++14.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • 1
    I'm selecting this as the answer, but I think it's unfortunate that it refers so extensively to C11 runtime-sized arrays. My understanding is that the feature in C11 is known as variable-sized arrays (VLAs), and, as noted by Yakk, there are important technical differences between (draft) C++14 runtime-sized arrays and C11 VLAs. My sense is that the key difference between runtime-sized arrays and `std::dynarray`s is that the former must be on the stack, while the latter may be on the heap. – KnowItAllWannabe Jun 28 '13 at 16:12
  • 1
    I find interesting the sentence *runtime-sized arrays are **first class** citizens*. While I understand the intention: they don't depend on the library but are native to the language; the fact is that runtime-sized arrays are far from *first class* citizens as there are quite a few things that cannot be done: `sizeof`, obtaining a pointer, cannot appear in function signatures, cannot be used as a member or template argument. The fact is that in C++ arrays are not *first class* citizens, not even the good statically sized arrays. – David Rodríguez - dribeas Jun 29 '13 at 02:18
  • *"not the least of which is the runtime `sizeof` that actual C11 runtime-sized arrays support."* - And thank god the C++ comittee didn't opt for this totally confusing `sizeof`-ambiguity (well, having an array on which `sizeof` doesn't even work isn't so good either, but if they chose to provide that rubbish feature runtime-sized-arrays are anyway, then it's good they chose the lesser evil for `sizeof`). – Christian Rau Jun 30 '13 at 18:06
  • I see that they support ranged based `for`, but do they support extractingthe length at runtime? Ie, did they replace the horrid `sizeof` with an equvalent alternative? @christianrau – Yakk - Adam Nevraumont Jun 30 '13 at 18:27
  • @Yakk Don't know (but don't think so either), I don't have much experience with them (mainly because I still try to ignore the fact that they will soon be a part of the language). Do they have free `begin/end` overloads? If yes, then there has to be some way to know it (well, except if `begin/end` was implemented by magic, too). If not, then they're even more useless anyway. – Christian Rau Jun 30 '13 at 18:55
2

As you said yourself std::dynarray will provide STL-style interface, which makes it more idiomatic to use. Still, C++ needs dynamic arrays created with new[] to:

  1. at least implement std::dynarray (so you can't have dynarray without new[])
  2. retain compatibility with previous versions

You can not just say that all code, which uses new[] is now wrong.

In general, the difference between C++14 std::dynarray and C++ new[] array is almost the same as difference between C++11 std::array and C-style arrays.

UPD: Now I see you are now asking about feature similar to C11 (VLA's). Actually there is nothing to do with it - VLA's are very limited and you can use only an argument of the function as your array size. Also, memory is allocated on stack, but for std::dynarray memory is allocated in the heap. Basically, this feature just extends C-style arrays a little bit more and makes C++ a bit more compatible with modern C standard.

billf
  • 112
  • 9
sasha.sochka
  • 14,395
  • 10
  • 44
  • 68
  • 4
    The question has nothing to do with `new`. Please see the clarification I added to the original question. – KnowItAllWannabe Jun 27 '13 at 22:05
  • 3
    Actually, C++ VLAs are not imported from C11 -- they are pretty different. For instance, in C++, `sizeof` is still compile time. In C11, `sizeof` might be run time. There are other differences.... – Billy ONeal Jun 27 '13 at 22:14
  • 2
    That's interesting. How could sizeof of dynamically sized array have compile-time sizeof? – sasha.sochka Jun 27 '13 at 22:15
  • 1
    If dynarray was always allocated on the heap, I don't see that as much of an improvement over `std::vector`. I believe the reality is far more complicated than that. – Mooing Duck Jun 27 '13 at 22:29
  • 2
    Per [the cited proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2648.html), the expectation is that memory for `std::dynarray` will be stack-allocated. – KnowItAllWannabe Jun 27 '13 at 22:31
  • 1
    @KnowItAllWannabe, here http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2648.html I see operator new[] in reference implementation – sasha.sochka Jun 27 '13 at 22:40
  • 1
    @MooingDuck, it will be more effective, as it will be closer to the rule "you don't pay for what you don't use". std::vector uses additional overhead memory to provide O(1) insertion but if you don't need that - you are wasting precious memory. Although yes, you are able to control std::vector using std::vector::reserve – sasha.sochka Jun 27 '13 at 22:42
  • 1
    @sasha.sochka when it isn't the size of the array that `sizeof` returns, but rather some other size (say, `sizeof` a pointer-to-first-element) that can be computed at compile time, or even making `sizeof` fail to work on it... – Yakk - Adam Nevraumont Jun 27 '13 at 22:43
  • 2
    @sasha.sochka: [The proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3662.html) points out that "we propose to define dynarray so that compilers can recognize and implement construction and destruction directly, without appeal to any particular standard library implementation. However, to minimize the necessary burden on compilers, we propose that dynarray can be implemented as a pure library, although with lost optimization opportunity." So heap allocation is permitted, but the expectation is that compilers are likely to use the stack instead. – KnowItAllWannabe Jun 27 '13 at 23:00
  • 1
    @KnowItAllWannabe, so that just basically means some compilers can implement from inside and make it built-in in the fact. Still, in the general case, it is implementation-defined, so you are not guaranteed to have it on stack. But you are guaranteed with C-style arrays. – sasha.sochka Jun 27 '13 at 23:08
  • 1
    @sasha.sochka: Yes, there is no guarantee that the memory for `std::dynarray` is stack-allocated, but the proposal makes clear that the design is such that such an optimization is possible. – KnowItAllWannabe Jun 27 '13 at 23:11
  • 2
    @sasha.sochka: N3691 5.3.3 [expr.sizeof]/1 "The sizeof operator shall not be applied [...] to an array of runtime bound." – Billy ONeal Jun 28 '13 at 07:37
2

I think you answered the question yourself, std::dynarray has the stl interface. A goal of c++11 and I'm assuming c++14 is to make c++ more user friendly, less error prone and easier for beginners. With c style arrays you may run into pointer arithmetic problems but dynarray avoids the problems if used as intended
EDIT: so it looks like one difference is that runtime-sized arrays must be allocated on the stack, increasing the likelyhood of a stack overflow. dynarray is allocated on the heap though it is possible to allocate on the stack (if the implementation did so)

aaronman
  • 18,343
  • 7
  • 63
  • 78
  • 4
    So why do we need runtime-sized arrays? Why not just adopt `std::dynarray` and be done with it? – KnowItAllWannabe Jun 27 '13 at 22:08
  • 6
    There is no backwards-compatibility issue here. C++11 doesn't have runtime-sized arrays. – KnowItAllWannabe Jun 27 '13 at 22:09
  • Maybe I'm not understanding your question, I'm under the impression that your asking why leave in the old c style arrays at all – aaronman Jun 27 '13 at 22:10
  • 1
    OP means variable length arrays. Automatic storage arrays with runtime determined size. – juanchopanza Jun 27 '13 at 22:10
  • So when he says runtime sized array he means vla – aaronman Jun 27 '13 at 22:12
  • @KnowItAllWannabe, maybe we need C++14 runtime-sized arrays to implement `std::dynarray`s more easily! I think the difference is that "C++14 runtime-sized" are a low-level language feature and `dynarray` is part of a library. There is no conflict: We have to distiguish between the core C++ language and the STL, some people don't have the luxury of using STL in their environments. – alfC Jun 27 '13 at 22:13
  • @alfC I think you mean the `std` library. – Yakk - Adam Nevraumont Jun 27 '13 at 22:13
  • @Yakk, maybe I do. I think STL applied more in this case because `dynarray` is or at least looks like a STL container. But thanks to pointing out that they are not the same thing. – alfC Jun 27 '13 at 22:18
  • @alfC: since (if I recall) VLAs must be on the stack, I don't think you can use them to implement `std::dynarray`, I don't think there's actually any relation between them. – Mooing Duck Jun 27 '13 at 22:27
  • @MooingDuck yes they have to be on the stack – aaronman Jun 27 '13 at 22:28
  • Also, if dynarray was always allocated on the heap, I don't see that as much of an improvement over `std::vector`. I believe the reality is far more complicated than that. – Mooing Duck Jun 27 '13 at 22:28
  • @MooingDuck here this [discussion](https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/YMFfP1hbJNE) talks about it a little – aaronman Jun 27 '13 at 22:30
  • @MooingDuck, since I am not familiar with C++14 runtime-sized array, I yet don't see why they cannot be used to implement `std::dynarray`. I guess it is because the runtime-sized (with its runtime size) cannot be a member of a class. – alfC Jun 28 '13 at 00:01
  • 1
    @alfC: That's _exactly_ the reason – Mooing Duck Jun 28 '13 at 00:02
  • @MooingDuck, however I am now confused because from the comments I read that `dynarray` is specially designed such that it can allocated in the stack, which makes me think: well, maybe through a certain stack allocated VLA. – alfC Jun 28 '13 at 01:01