Why both runtime-sized arrays and std::dynarray in C++14?
Asked Answered
A

3

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.

Amplitude answered 27/6, 2013 at 21:54 Comment(9)
What are you comparing dyn array toAgace
To runtime-sized arrays (described here.)Amplitude
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.Endometriosis
@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.Endometriosis
You almost have something like dynarrays already with std::unique_ptr<T[]>, but that one lacks iterators. That said, the difference is not very big. Variable-length arrays on the other hand are something completely different.Goer
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.Scumble
Stroustrup's comment about not adding C99-style VLAs to C++11 is interesting: "Not VLAs (Variable Length Arrays; thank heaven for small mercies)."Scumble
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).Arithmetic
For anyone who may find this, std::dynarray was removed from the C++14 standard. See comment CH 2 In the official status. If you need this functionality, please use Boost.Pannonia
T
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.

Tonyatonye answered 27/6, 2013 at 22:12 Comment(5)
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::dynarrays is that the former must be on the stack, while the latter may be on the heap.Amplitude
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.Scummy
"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).Inelegant
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? @christianrauTonyatonye
@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.Inelegant
E
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.

Erie answered 27/6, 2013 at 22:1 Comment(12)
The question has nothing to do with new. Please see the clarification I added to the original question.Amplitude
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....Coppola
That's interesting. How could sizeof of dynamically sized array have compile-time sizeof?Erie
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.Margarite
Per the cited proposal, the expectation is that memory for std::dynarray will be stack-allocated.Amplitude
@KnowItAllWannabe, here open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2648.html I see operator new[] in reference implementationErie
@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::reserveErie
@Erie 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...Tonyatonye
@sasha.sochka: The proposal 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.Amplitude
@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.Erie
@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.Amplitude
@sasha.sochka: N3691 5.3.3 [expr.sizeof]/1 "The sizeof operator shall not be applied [...] to an array of runtime bound."Coppola
A
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)

Agace answered 27/6, 2013 at 22:1 Comment(15)
So why do we need runtime-sized arrays? Why not just adopt std::dynarray and be done with it?Amplitude
There is no backwards-compatibility issue here. C++11 doesn't have runtime-sized arrays.Amplitude
Maybe I'm not understanding your question, I'm under the impression that your asking why leave in the old c style arrays at allAgace
OP means variable length arrays. Automatic storage arrays with runtime determined size.Orms
So when he says runtime sized array he means vlaAgace
@KnowItAllWannabe, maybe we need C++14 runtime-sized arrays to implement std::dynarrays 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.Endometriosis
@Endometriosis I think you mean the std library.Tonyatonye
@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.Endometriosis
@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.Margarite
@MooingDuck yes they have to be on the stackAgace
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.Margarite
@MooingDuck here this discussion talks about it a littleAgace
@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.Endometriosis
@alfC: That's exactly the reasonMargarite
@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.Endometriosis

© 2022 - 2024 — McMap. All rights reserved.