I really liked variable-length arrays in C. They were almost like automatic memory management in C.
The problem with VLAs on the stack in C is that you need to be very careful that the attacker can’t influence the size. If they can, then they can induce stack overflow. This means, to use them safely, you have to impose a sensible maximum size and fall back to heap allocation in other cases, which means you still need to write the code for the cleanup and you still have a fixed maximum size. At that point, you may as well just have a fixed-size stack allocation, which will generate better code in the compiler anyway. LLVM’s SmallVector class handles all of this in C++ for you: allocates a fixed-size buffer on the stack and transparently falls back to heap allocation if you need something larger. I’ve written C macros that do this using __attribute__((cleanup)), but eventually I gave up and just used a language that had a proper mechanism for doing it.
Indeed, it’s a pity that many C replacements (notably Zig) don’t have that feature.
It’s not built-in in zig but it’s easy to build a stack-backed allocator using FixedBufferAllocator and then add a heap allocator as a fallback.
I feel if they let you control how VLAs were allocated, they wouldn’t become the despised footgun they are now.