4 ms·
The real tragedy of the C language is that VLA are not implemented safely in any known implementation. They are so natural to use! Any pair of malloc/free on
by enriquto 7y ago
The real tragedy of the C language is that VLA are not implemented safely in any known implementation. They are so natural to use! Any pair of malloc/free on the same scope could be cleanly replaced by a single VLA declaration.
- jpfr 7y agoAll C compilers I know either have VLA or alloca. In one of my projects, a bit of macro magic uses either VLA or alloca to generate a temporary array. Works great! I don't have further requirements here. Please explain what you mean by "safe" in this context.
- enriquto 7y agoI mean a way to control for stack overflow. I would like to allocate very large images as VLA, where the size is only known at runtime. If I malloc a too large image, the systems asks for more memory or malloc fails. If I declare a VLA too large, it fails silently in an unrelated part of my program due to stack corruption.
- devit 7y agoCorrect implementations use stack probing (access one word for every page in the allocation) to guarantee that a stack overflow happens immediately rather than resulting in stack corruption.
- enriquto 7y agoAlright, but that doesn't really solve anything, does it? It just makes the problem easier to debug.
- thenewnewguy 7y agoWhat's the problem, that the stack is capable of being overflowed? How do you expect the C compiler to fix that?
- enriquto 7y agoThe stack is not a concept belonging to the C language definition, it is just an implementation choice made by some compiler vendors (all that I know of). The semantics for VLA are clear and very useful. I would certainly not expect that the memory for VLA is implemented on the same stack as the function call stack. My complain for C programming (what I called its "tragedy") is that no compiler provides a mechanism for safely using all available memory via VLA. Edit: you may answer: "use alloca then". But the syntax for alloca is not that convenient, and the semantics are very different. A common use for VLA is to declare a temporary array inside the body of a loop, this is not possible with alloca.
- gmueckl 7y agoWhat platform are you on that cannot detect a stack overflow?
- enriquto 7y agoI do not know how to do it on any platform. My problem is this: void f(int n) { float t[n]; // what do I write here to check if everything is OK ? ... }
- dmitrygr 7y agoModern gcc handles this very well actually. Here: https://gcc.gnu.org/onlinedocs/gccint/Stack-Checking.html https://gcc.gnu.org/onlinedocs/gccint/Stack-Checking.html
- pm215 7y agoI used to work on a (now defunct) RTOS whose C runtime didn't support alloca. Functions were all compiled down to a portable bytecode representation that had to statically declare the stack usage, so there was no way to have a function with variable stack size. Not having a real alloca was occasionally an issue for porting C code to it (but less annoying than not having fork()).
- wahern 7y agoVLAs were added to satisfy the FORTRAN crowd, who are used to efficiently instantiating huge arrays on the stack. AFAIU, you can't catch stack overflow in FORTRAN either. That doesn't mean that they're not safe, so long as the program reliably terminates[1]. And you can catch stack overflow, it's just not easy, and made especially difficult from a software architecture perspective because neither C nor POSIX support per-thread signal handlers, so catching stack overflow requires cooperation across components and libraries. (Fortunately, POSIX does provide per-thread signal stacks via sigaltstack(2). And I suppose it should be possible to write a shared library that interposes pthread_create and signal/sigaction to support per-thread signal handlers.) TL;DR: VLAs are fine if you're doing something you might otherwise be doing in FORTRAN. Otherwise, just don't. It's trivial to use GNU obstacks or to write your own, as I do. Just don't go down the rabbit whole of trying to solve all allocation needs; it's not a solvable problem. [1] Sadly, before Stack Clash was published neither GCC nor clang/LLVM did this :(
- pjmlp 7y agoLinux project has decided to eradicate VLAs from kernel space and they are now forbidden for new code. Reason? Several security exploits.
- kazinator 7y agoFunction calls are not implemented safely in C. If there is no space for the next activation frame, the behavior is undefined. Allocating a non-VLA is not safe. Your running program's char x[4096] could go spectacularly wrong.
- enriquto 7y ago> Your running program's char x[4096] could go spectacularly wrong. This is a tiny size, and it would never pose a problem. I'm talking about allocating a few high-resolution video frames on a VLA for temporary computation. It is extremely natural to declare these temporary space inside a for loop as for (...) { float frame[3*width*height]; // temporary data ... } but due to the "unsafety" of the VLA implementation it is not very portable. To make it safe in my linux computer I just set "ulimit -s" to a huge value and it works. But it is not very practical to distribute such code to others.
- kazinator 7y ago> This is a tiny size, and it would never pose a problem. Cribbed from some Unix programmer's epitaph.
- pjmlp 7y agoThat is the tragedy of almost every major feature, because speed trumps safety.