Hacker News new | ask | show | jobs
by uecker 987 days ago
VLA were not removed. VLAs are almost always better than the next best alternative: - They are better than alloca due to proper scoping and standard compliance. - They use less stack than regular arrays on the stack with a worst-case size (e.g. a divide-and-conquer algorithm that may need O(N^2) stack space without VLAs could potentially be written using O(N log(N))) - VLAs can allow more accurate bounds checking than with worst-case sized arrays. - VLAs are faster than heap allocation.

There are issues with VLAs: If the size is controlled by an attacker, then this could cause security issues. This is largely mitigated by -fstack-clash-protection which transforms this into a DOS (same as unbounded heap allocation) and you want to have stack clash protection anyway. Static analysis tools and compiler flags can also help to detect cases where the size is controlled by input from the network. Assembler for VLAs worse than for fixed size array, but this goes at the cost of less space saving. But, again, people who avoid VLAs blindly because of these issues then often use something which is worse.

Also note that most other languages except C++ also have VLAs.

2 comments

> VLA were not removed.

They were made optional in C11, which for real-world purposes makes puts it on the same level as a compiler-specific language extension. For instance MSVC will (most likely) never support VLAs:

https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-...

(specifically: https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-...)

The difference is that if there are there, you get consistent behavior across all compilers that support them. MSVC was essentially stuck with pre-C99 for a long time. So nobody in their right mind would use it for C programming if he had a choice. Now they are catching up. Let's see how this goes. We made variably modified types mandatory in C23. I hope we make VLAs mandatory again in the next revision.
> Also note that most other languages except C++ also have VLAs.

I don't think that's actually true.

Lots of modern languages have "pointer plus length"--they call them lots of different things but I think "slices" is a common term. But those aren't VLAs.

Some languages have variable vectors backed by a compile-time fixed-size array (See Zig: BoundedArray). But, again, not a VLA.

I'm trying very hard to think of a non-GC language that allows you to allocate a run-time length array on the stack other than C, and I'm not coming up with one.

Yes, pointer + plus length is something else.

C has variably modified types (in CS usually known as dependent types), where the length is encoded into the type. A VLA has a dependent type: char buf[n] or a pointer to a VLA has: char (*buf)[n]. This is super powerful and theoretically sound concept although not yet really exploited in C. But the bound travels with the type and you can get bounds checking at run-time:

char buf[n]; auto foo = &buf; buf[n] = 1; // run-time bounds check possible

Pascal, Ada, Fortran, D have VLAs and certainly more languages have VLAs.

I don't think D has VLAs.

Between the fact that most modern languages don't have VLAs and that the languages you mention are most certainly not modern, your statement of: "Also note that most other languages except C++ also have VLAs." is not even close to correct.

D has dynamic arrays which can be on the stack. At least it looks to me like this: https://godbolt.org/z/vTqMah569

I guess this depends on whether you count higher level languages with GC which often have some kind of automatically managed dynamic array / vector type but not necessarily call them VLAs.

I also did not say "modern" - not that this is clearly defined. If you only count Zig and Rust as modern, then those two do not have VLAs as far as I know. But this was not my main point anyway.