33

In C99 this was legal:

void f(size_t sz) {
    char arr[sz];
    // ...
}

However, this - dynamically sized stack arrays - has been dropped in C++, and not seeing a return in C++11.

AFAIK C++ was made with C compatibility in mind, so I wondered There must be some very good argument of not including this useful feature, right?

All I could think of was this:

Pros

  • Memory savings by allowing smarter array sizes that need to be on the stack (temporary buffers?).
  • Less "smart pointers" (or worse, manual bug-introducing delete []'s) and slow heap allocations.
  • Compatibility with C99.

Cons

  • Allows people to easily allocate too large arrays on the stack giving hard-to-debug stack overflows.
  • More complicated for compiler writers.

So, why did they didn't they include it when they imported other C99 features?


To prevent this from being closed as "subjective" or "not constructive", I'm looking for quotes from commitee members or links to discussions talking about the matter - with bonus points for a quick SO roundup of course.

Rather than seeing this as a Ponies vs Hamsters discussion, see it as a historical question, mere interest in the advantages and disadvantages that were considered (if at all).


EDIT: As James McNellis pointed out in the comments below C++ existed before C99 standardized variable-length arrays. You might read my question then as: "Why didn't and won't they add it?".

Community
  • 1
  • 1
orlp
  • 112,504
  • 36
  • 218
  • 315
  • 19
    It hasn't been "dropped" because it was never part of C++. – James McNellis Sep 18 '11 at 01:06
  • @Anonymouse downvoter: Is my question unclear or doesn't show research effort? I'm willing to debate how useful it is though, here's my argument: I think it would help my understanding of C++ a tiny tad more. At closing voter: I think this applies: _"We expect answers to generally involve facts, references, or specific expertise"_. – orlp Sep 18 '11 at 01:07
  • @James McNeillis: It was indeed never dropped. But several other C99 features were added, why not dynamic local arrays? I've wondered myself. Getting rid of the `alloca` nonsense was a very good change to C. – Omnifarious Sep 18 '11 at 01:09
  • 1
    I think this applies: *this question will likely solicit opinion, debate, arguments, polling, or extended discussion.* – Daniel A. White Sep 18 '11 at 01:10
  • 6
    BTW, this seems to me like a clear question with a definite answer. It doesn't seem subjective, and while the term 'dropped' is a bit loaded and not entirely accurate, I think that's a minor nit. – Omnifarious Sep 18 '11 at 01:11
  • +1, this is a great question. Maybe you just need to word it differently so people don't get pedantic about "it never existed in C++". The question of "why doesn't C++ allow dynamic stack arrays" is excellent though. For such a fundamental feature to be left out after so many obscure features being added, there must be a good objective reason. – tenfour Sep 18 '11 at 01:12
  • I removed the term "dropped" for the more appropriate "not included". – orlp Sep 18 '11 at 01:12
  • 2
    I think the requirement of quotes from committee members puts this into 'not a real question' (unanswerable) territory. Perhaps the answer is just "no one cared enough about it"? I doubt there would be quotes to that effect. – SoapBox Sep 18 '11 at 01:13
  • @Daniel: Nah, It think it's a great question. +1 – user541686 Sep 18 '11 at 01:13
  • This falls into subjective *"Why didn't and won't they add it?"* – Daniel A. White Sep 18 '11 at 01:14
  • 2
    How is this soliciting debate or opinion? There are only hard facts: `pro`'s and `con`'s. To put it in stackoverflow style: I don't give a **** about what you actually think is right, I just want to know __why__ - reasons. – orlp Sep 18 '11 at 01:16
  • My answer before the edit was "Variable length arrays were introduced in C99. C++ was based on older versions of the C standard. So, they were not dropped from C++ — they were never part of C++.", I am erasing it since it does not make sense anymore after the edit. – CesarB Sep 18 '11 at 01:16
  • Brainstorming: In C++, arrays of various sizes are each a unique type, which allows you to pass them by reference to functions retaining their size instead of them decaying to pointers. How would this work if arrays could be dynamically sized? – Benjamin Lindley Sep 18 '11 at 01:16
  • 2
    @Daniel A. White: He isn't asking for anybody's personal opinion as to why it wasn't added, he's asking for the committee's opinion, which is a matter of record and a clear fact that is not open to debate. Even if it wasn't added because nobody cared enough to even mention it, that's also a matter of record and not subjective. – Omnifarious Sep 18 '11 at 01:17
  • hence that is why it is subjective. many questions that start out with "Why" are subjective. – Daniel A. White Sep 18 '11 at 01:17
  • 38
    I'm kind of surprised that people get so fond of closing "Why?" questions as "subjective". IMHO, **many of the *best* questions on StackOverflow are indeed the "Why" questions.** (**See [here](http://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result).**) Just because multiple people can have multiple guesses as to the answer doesn't mean that there isn't a right answer. I think people should chill down a bit and allow questions like this to go on, instead of closing them on the spot just because *they* can't think of an objective answer. :\ – user541686 Sep 18 '11 at 01:17
  • 2
    @Daniel A. White: _Why do cooks hit their meat before they cook it?_ _Why is the earth round?_ _Why do people still program (pieces) of code in assembler?_ _Why do we exist?_ (joking) Many "why"-questions are interesting hard-fact questions. – orlp Sep 18 '11 at 01:18
  • @nightcracker - you are asking us to understand the decisions made by the c++ committee. – Daniel A. White Sep 18 '11 at 01:20
  • @Daniel A. White: No, I am asking for their _considerations_, their _arguments_, their _pros and cons_. – orlp Sep 18 '11 at 01:21
  • 2
    hence then there is no correct answer, its just extended discussion. – Daniel A. White Sep 18 '11 at 01:22
  • 1
    @Daniel A. White: Excuse me dear Daniel, but now you are just saying that history in general is merely subjective, with which I disagree. Here's another why question of mine, subjective too? http://stackoverflow.com/questions/4752715/why-are-both-little-and-big-endian-in-use – orlp Sep 18 '11 at 01:23
  • 1
    @Daniel: If there wasn't so much meta-discussion about the question itself, then maybe we'd be able to observe whether it would *actually* generate discussion about the topic... but right now, these unnecessary close votes (and the discussions they're generating) are worse than what they're trying to prevent. – user541686 Sep 18 '11 at 01:23
  • 5
    The reason for closing questions is to preserve the quality of content on SO. Of all the crappy questions that remain, how is *this* question generating this much controversy? Just leave it open; it's helpful and interesting. – tenfour Sep 18 '11 at 01:24
  • 2
    I believe that `std::dynarray` was/is proposed for C++ tr2. – Johannes Schaub - litb Sep 18 '11 at 01:26
  • 3
    Please move this discussion to chat. – Robert Harvey Sep 18 '11 at 01:27
  • 5
    This isn't a bad question because it's subjective, it's bad because it's a duplicate. :-) – Omnifarious Sep 18 '11 at 01:45
  • 1
    The comments under this, as well as _both_ answers more than illustrate why I closed this: "_this question will likely solicit opinion, debate, arguments, polling, or extended discussion._" Anyone is free to take this to Meta. This has gone through one open/close bout already. I'm sorry, but Stack Overflow is _not_ the best place for this type of question. – Tim Post Sep 18 '11 at 02:23
  • @Tim Post: What place(s) would you suggest instead? I often use SO for border-line on-topic questions that would be better suited with a forum, but I haven't found a single forum yet that comes even close to the quality of SO. – orlp Sep 18 '11 at 02:52
  • 2
    This is a duplicate of http://stackoverflow.com/questions/1887097/variable-length-arrays-in-c . And, @Tim Post: The only reason half of that discussion happened was because people were closing it for stupid reasons. – Omnifarious Sep 18 '11 at 03:07
  • 1
    @Tim: The discussion was a meta-discussion about the votes, not an actual discussion about the question. So it's really unfair to say that the question draws opinion/polling/arguments/whatever -- it has nothing to do with the quality of the question itself, but people being overly paranoid about what they think is a good for SO. I don't think it makes sense for anyone to take this to Meta, though, since it should obviously be closed as a dupe anyway (although I think some users would have liked to see that be the close reason instead, myself included). – user541686 Sep 18 '11 at 03:38
  • Fact: the VLA support is impossible with c++ because of sizeof, and std::vector already implements same feature, and thus VLA is not needed in c++. Even in C the feature is broken because you cannot put such an array inside a struct. There is no reason to include it to c++. – tp1 Sep 18 '11 at 04:27
  • voted to reopen, so it can be re-closed as duplicate of [this](http://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard) – M.M Oct 27 '16 at 00:02
  • Variable sized arrays on the stack were part of ISO C++14, they were added to and have remained in GCC and Clang, Microsoft's compiler never supported them. As I understand it the argument against was that the variable value used for the size could create an array larger than the stack frame, so you need to be somewhat careful about checking the value limits when they are used. – Max Power Jan 12 '23 at 21:33

2 Answers2

21

I think, it's because C++ provides superior solutions: std::vector<T> and std::array<T,N> (C++11); though the latter is not dynamic as such but it's superior to raw arrays. You can always know the size, no matter which function you pass the vector or array.

Since C cannot provide these solutions, C99 came up with Variable Length Array (VLA). It has the same problem as regular arrays: it decays into a pointer on passing it to function, and you no longer know the size of the array.

And as Florian Weimer asked here at comp.std.c++ that if C++0x allows VLA, then what would the following code mean?

int vla[n]; //n is known at runtime!
std::vector<decltype(vla)> v; //what does this mean?

How is the compiler going to instantiate the vector template at compile-time when it's type argument depends on n which is known at runtime?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 4
    If you -1 something, it's only polite to say why. – Omnifarious Sep 18 '11 at 01:25
  • 3
    @Downvoter: please specify the reason so others and me can know why this answer is silly; and how it can be improved. – Nawaz Sep 18 '11 at 01:26
  • 3
    This is a valid answer, if you disagree don't just blindly downvote but say in the comments. Please read the tooltip of the downvote button: _"this answer is not useful"_. I disagree with that on this particular question. – orlp Sep 18 '11 at 01:27
  • 3
    I didn't -1'ed, but I don't agree "C++ solutions are superior": maybe they are in a lot of contexts. But after having profiled carefully a piece of code I recently had to write, the only sensible options were a static vector or gcc's VLA extension, to avoid too frequent heap allocations. I chose vector for portability, but this left me with a not thread-safe function (which is waiting for "thread_local" implementation). In this case, knowing the size outside of the function was uneeded, and VLA _was_ superior to std::array (btw, i couldn't understand why std::array was so slower than VLA). – rafak Sep 18 '11 at 12:24
  • @rafak: You can easily avoid `"too frequent heap allocations"` in Standard C++ as well. – Nawaz Sep 18 '11 at 12:44
  • @Nawaz: yes I'm not aware of every solutions for sure, but VLA was the most straighforward one I could come with. And for example writing a custom allocator was out of question for such a localized need. – rafak Sep 18 '11 at 14:56
  • 3
    @Nawaz: `std::vector` initialises its elements, which may incur an unacceptable performance hit in some cases. The `decltype` issue is a red-herring; the compiler could simply disallow it, as does the Objective-C++ compiler: `Variably modified type 'decltype(a)' (aka 'int [n]') cannot be used as a template argument`. – Marcelo Cantos May 04 '13 at 05:44
  • Why would heap allocation be superior to stack allocation? – Micah Jul 22 '14 at 16:43
  • 1
    @Yiuin: Who said that? – Nawaz Jul 22 '14 at 17:00
  • 3
    You said that C++ provides superior solutions, however std::vector is stored on the heap, std::array isn't dynamic. I fail to see how they are superior. Lets be honest, this was added to the C standard after C++ was invented, and so it just never got included. Its also harder to implement, as most variables on the stack are usually referred to as stack+4 or stack+8 or whatever constant. So you then have to keep an offset variable for every stack variable. – Micah Jul 23 '14 at 23:29
  • @Yiuin: C++'s `std::vector v(big_size);` vs C99's `big_type a[big_size];` Which one is more safe against Stack Overflow? – Nawaz Jul 24 '14 at 04:01
  • First: the stack size limit is arbitrary and can be changed. The stack and heap grow towards each other, and with 64bit address overflow is basically impossible. Second: While it may be bad to allocate a large data-set of unknown type on the stack, because you could hit the system limit, there are a lot of cases where you may know the order magnitude of the variable that you are allocating. Third: Hitting the stack limit isn't that bad. Its a segfault. So dynamic stack variables are preferable to a fixed buffer which could lead to overflow (if poorly managed) – Micah Jul 24 '14 at 19:23
  • 1
    After thinking on this more, I think Nawaz is right in that the need was more pressing in C because it lacks variable-size data structures that may be automatically deleted, which of course could lead to memory leaks. – Micah Jul 26 '14 at 01:19
  • Runtime-sized arrays with automatic storage duration (on stack) were part of the proposed ISO C++14 but didn't make the final cut. They were added to and have remained in both GCC and Clang, Microsoft's compiler never supported them. As I understand it, the arguments against centered around the potential that the variable value could create an array larger than the available stack space if the programmer is not somewhat careful about checking the value limits. – Max Power Jan 12 '23 at 21:53
2

This functionality largely duplicates that of std::vector, except that it consumes a more limited resource (stack vs heap space). As such, there is not really any need for it in C++, semantics-wise.

One could argue that on-stack allocation can improve efficiency (particularly in the face of multiple threads); however, this can also be achieved in C++ using custom allocators to build a private memory pool, either on the stack or heap. This is again more flexible than placing memory on the stack, and indeed you could create a custom allocator that carves chunks out of an on-stack memory buffer easily enough. It's not exactly the same as dynamic array semantics, but the existence of custom allocators and STL containers covers most use cases you'd want stack allocation.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • 1
    Was there a discussion to that effect? One thing that comes to my mind is that stack space is automatically thread-local, and that can be a very useful thing because it makes allocating stack space very fast as compared to allocating heap space on many implementations. But I can understand if that fact was considered and found not compelling. I'm just curious. – Omnifarious Sep 18 '11 at 01:24
  • 3
    @bdolan: Stack space is O(1) speed allocation, which is great for things like file names (which are around ~256 characters *max*). Heap allocations are comparatively *much* slower, and applications that work with small strings could often greatly benefit by using the former instead of the latter. So I'm personally not convinced that there isn't a "need" for it in C++. (Otherwise, why do compilers implement `_alloca` so often?) – user541686 Sep 18 '11 at 01:26
  • I don't know if this was actually discussed in the standardization process, but it seems a reasonable reason to exclude it. Yes, local allocation can be marginally more efficient, but a lot of malloc implementations have thread local pools anyway, and for larger allocations, the cost of construction exceeds that of allocation anyway. – bdonlan Sep 18 '11 at 01:28
  • @Mehrdad, `std::string` implementations often have small strings allocated within the object anyway... – bdonlan Sep 18 '11 at 01:28
  • @bdonlan: Really? I didn't know that -- I mainly use MSVC and I hadn't observed that before. Would you please provide a link? – user541686 Sep 18 '11 at 01:29
  • @Mehrdad: "why do compilers still have _alloca" - because it's in their C runtime library, and it would be extra effort to block it from C++ use, solely to impose a programming style? I suspect there are use cases of C++ where alloca and/or VLAs appear vaguely useful, at least to the extent they're useful in C99. But even if there wasn't any use, it's not surprising that implementations make it visible from C++. – Steve Jessop Sep 18 '11 at 01:31
  • @Mehrdad, not all implementations do it, but some do: http://stackoverflow.com/questions/1466073/how-is-stdstring-implemented/1466658#1466658 – bdonlan Sep 18 '11 at 01:31
  • @Steve: If you suspect that's the reason, then how come Microsoft even introduced `_malloca` and `_freea` to *help* developers allocate memory on the stack, and debug overflow issues? Surely that's extra effort on MS's part, and for good reason? – user541686 Sep 18 '11 at 01:32
  • @bdonlan: Do you happen to know of any actual implementations that do this, or is it simply mentioned as a theoretical possibility? (I didn't find any in the link.) – user541686 Sep 18 '11 at 01:33
  • @Mehrdad, according to this article, STLport does this: http://complement.sourceforge.net/compare.pdf – bdonlan Sep 18 '11 at 01:34
  • @Mehrdad: My claim is not that this is the reason. My claim is that part of your argument does not follow, because *even if* alloca were viewed as useless by C++ implementers, some of them would still probably throw it in because they've already got it lying around for C. Hence, the existence of alloca in C++ implementations is not the smoking gun you think it is. – Steve Jessop Sep 18 '11 at 01:38
  • @bdonlan: Oh wow! I'm trying to find the part of the [source code](http://stlport.git.sourceforge.net/git/gitweb.cgi?p=stlport/stlport;a=tree;f=stlport/stl;h=bab17499c83a703ec7c66e48bd13ec09af49bf68;hb=refs/heads/master) that does this but can't find it. In any case, though, I might end up switching to STLPort in Visual Studio... this is actually important in some of my programs. Thanks for the link! :) – user541686 Sep 18 '11 at 01:39
  • @Steve: But your argument only works for `_alloca`, not `_malloca`: why, then, was this function created? – user541686 Sep 18 '11 at 01:40
  • @Mehrdad: in the case of MS, since they don't implement C99 in general, and support C development at all only under protest, it seems likely to me that they support VLAs and all variants of alloca because they think they're useful. Indeed, by guaranteeing behaviour on stackoverflow, `_malloca` overcomes the major pointlessness of VLAs -- it's more useful than VLAs and therefore worth some effort. IIRC they use it themselves for converting filenames etc between ASCII and unicode. But in general, C++ compilers can compile C99 or something close to it, MS is a special case of a C99 refusenik. – Steve Jessop Sep 18 '11 at 01:49
  • 1
    @Mehrdad: The Visual C++ 2010 `std::string` implementation uses the small-string optimization. – James McNellis Sep 18 '11 at 01:52
  • @James: I hadn't looked at 2010, and I hadn't noticed any indication of in 2008 (but I could've missed it). But that's great to know; thanks for letting me know! – user541686 Sep 18 '11 at 01:54
  • @Steve: Oh, and it's worth mentioning that C# also supports `stackalloc` for the same reason -- and tons of people use it. You could say Microsoft is an "exception", but IMHO if it's an exception then it might as well be another rule of its own (the fraction of people that use MS development tools isn't exactly what I could consider negligible). – user541686 Sep 18 '11 at 02:21