4 ms·
So adding a if (n > MAX){ return; } Would not help?
by craftyguy 8y ago
So adding a
if (n > MAX){
return;
}
Would not help?
- benchaney 8y agoChoosing an appropriate value for MAX could potentially be quite difficult.
- olliej 8y agoAs @benchaney said you have to choose an appropriate guard. But the issues with VLAs are many * the code is bigger, and people say is meaningfully slower * super easy to accidentally blow the stack - in kernel land that is probably going to end in a panic * using vLAs used to disable stack canaries for those frames, not sure if it still does For a lot of cases where you are truly going to need variable length you’re unlikely to be penalised heavily by a heap allocation due to the relative cost of the operations.
- jcelerier 8y ago> meaningfully slower really ? there's a difference but unless you keep allocating in a hot-loop this should hardly ever have observable costs : https://gcc.godbolt.org/z/SN9Ois https://gcc.godbolt.org/z/SN9Ois
- pjmlp 8y agoYes there is a talk done by Google at Linux Kernel Security Summit 2018 about it.
- jabl 8y agoThe problem is with how to access other variables on the stack. Usually the compiler uses an offset from the stack pointer, which without VLA's is known at compile time. However, if you have VLA's, you might need a calculation at runtime to figure out where that variable is stored. Or maybe the offset from the frame pointer is known statically, but then you can't do the "omit frame pointer" optimization and you thus waste a register. Or if you have a variable that is between two VLA's, then you need a runtime calculation regardless.
- leeter 8y agoI think it's worth noting that in kernel-land most things have fixed maximum sizes anyway. So while a VLA may seem like it's saving time it is probably cheaper to just use a fixed size array in most situations. In the cases where you really need something of dynamic size I suspect kmalloc isn't that expensive vs the pain that an implicit alloca can have at the wrong time. I'd also guess they probably don't play well with some interrupt handling code as well, as most interrupt handlers can't trigger a page fault or the kernel will panic. It's also worth noting that in general kernel stacks are usually much smaller than userland stacks almost to the point of painful.
- craftyguy 8y agoThanks for the more detailed explanation!
- Dylan16807 8y agoIt would help a little bit, but not enough. And if a small buffer will do the job, you can always use m[MAX].
- burfog 8y agom[MAX] means you can't usefully use sizeof A really nice use for a VLA would be in the middle of a struct. You could make something like a PNG image file chunk as a struct, with the CRC at the end coming after the VLA. You get a struct of the correct size with the right fields, despite one part of the struct being of variable size.
- SamReidHughes 8y agoYou’d need the VLA length encoded somewhere in the struct, though.
- burfog 8y agoNo you don't. It is a separate variable. For example, a parameter n is passed to a function, and then a struct is defined based on n. struct { uint32_t header; uint32_t array[n]; uint32_t footer; }foo; The function fills in the struct. Maybe it then sends the struct via a packet-oriented protocol, perhaps over a datagram socket, so the length is transmitted implicitly in the packet size.
- SamReidHughes 8y agoThat’s different from a VLA, which doesn’t use dependent typing or any reliance on users keeping variables unmodified to guarantee they clean up the stack properly.
- burfog 8y agoIt is a VLA. See the second example: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html There is no problem cleaning the stack because the compiler has numerous ways to do that. One way is to keep a copy of the original n, as passed to the function. Another way is to save the original stack pointer. Making this work is not much harder than supporting the alloca function.