4 ms·
He's talking about variable length arrays, which would be an unsized type in Rust and thus can't be stack allocated. For example, the following is valid C99: `
by akiselev 6y ago
He's talking about variable length arrays, which would be an unsized type in Rust and thus can't be stack allocated. For example, the following is valid C99:
`void foo(int n) { int values[n]; }`
I don't know that that's a bad thing. AFAIK the implementation details are underspecified even in C and compilers kind of do whatever they want (i.e. I've seen some embedded compilers that monomorphize it in multiples of 2 up to a limit and just hope the user doesn't exhaust the stack).
Edit: I'm pretty sure you can create a hacky version using iterators and a recursive function: `fn vla<T>(iter: impl Iter<Item=T>, init: T, index: usize, count: usize) { ... }`
Edit2: Actually he's talking about `alloca` which is a whole other "here be dragons" feature. See the reddit thread steveklabnik linked for some of the pitfalls
- masklinn 6y ago> Edit2: Actually he's talking about `alloca` which is a whole other "here be dragons" feature. See the reddit thread steveklabnik linked for some of the pitfalls AFAIK VLA is already that, didn't Linux de-VLA the kernel a few years back because they were a common security issue and the code they generate is bad / slow?
- gpderetta 6y agoAt least in gcc, vla and alloca prevent inlining.
- vvanders 6y agoEven then last I looked C++ doesn't have it either, it's exclusively a C99 feature. For me the downsides outweigh the upsides of alloca and I usually find other approaches(free list, arenas, etc).
- Someone 6y agoWhen comparing rust and C++, I think it’s unfair to interpret “C++” as a specific standard, because you can’t do the same with rust. So, you would have to compare implementations. AFAIK, in practice, many C++ compilers support alloca for compatibility with gcc (or more specifically, its C library) Also, is alloca part of any C standard? I can’t find evidence for that easily. Also, if so, https://en.wikipedia.org/wiki/Stack-based_memory_allocation#System_interface https://en.wikipedia.org/wiki/Stack-based_memory_allocation#... needs updating. It currently says “The function was present on Unix systems as early as 32/V (1978), but is not part of Standard C or any POSIX standard.” I also don’t see how it could be part of the standard, as that, AFAIK, doesn’t even specify the existence of a call stack (a compiler is free to allocate call frames on the heap, for example)
- vvanders 6y agoMost C++ compilers I've worked wouldn't let you use it unless the compilation unit was compiled as C and then linked externally. In the same way I could totally define alloca in a C symbol and then just extern it into Rust if I wanted to. [edit] Realized I was thinking of VLAs but I think the point still stands.
- Someone 6y agoReading https://www.gnu.org/software/gnulib/manual/html_node/alloca.html https://www.gnu.org/software/gnulib/manual/html_node/alloca...., I think gcc C++ supports alloca on most systems (“There are a few systems where this is not possible: HP-UX systems, and some other platforms when the C++ compiler is used. On these platforms the alloca module provides a malloc based emulation”) VLAs are different, I think.
- gpderetta 6y agoC has standardized dynamically sized automatic arrays which is close enough to alloca. The standard wouldn't concern itself of were the space is actually allocated, just mandate that it is freed when the function terminates.
- kllrnohj 6y agoI've found just applying SSO to the container sufficient. Stack if it's small enough, heap if it isn't. You usually want a limit on your alloca anyway.
- dathinab 6y agoAs a side note RFC#1909 is a accepted RFC which introduces unsized rvalues to rust allowing VLA's. BUT: - it's not implemented (maybe partially? idk.) - it has unclear/non-trivial interactions with async-await transformation, ~mainly the generator does need support for multiple unsized values, which isn't supported by rust but can be archived through some hacks in that specific case~ Edit: It turns out it's actually not really possible to use unsized values in generator which life across await/yield boundaries, as far as I can tell. So it's one of the "it's not hear yet" situations.
- akiselev 6y agoSadly, after trying specialization and obsessing over GATs threads/issues, I've learned not to get my hopes up about such complex features with so many subtle implications landing in stable any time soon :( - I've still got PTSD from all the compiler panics. > - it has unclear/non-trivial interactions with async-await transformation, mainly the generator does need support for multiple unsized values, which isn't supported by rust but can be archived through some hacks in that specific case. This especially gives me pause. I've thoroughly enjoyed the async/await experience in Rust despite its rough edges but it seems the community's exploration of async/await is still in its early stages. It sounds that something as complex unsized rvalues will take a long while to get right (I don't know what I'm talking about though, so please correct me!)
- dathinab 6y agoYes, also just after posting I noticed you can't have unsized values living across await in generators without some major changes or something. The problem is that when you create a generator it doesn't yet know the unsized field it only knows it when creating it in a `poll` call. But it only will call poll after pinning the generator at which point you can't really grow the size of it for a bunch of reasons including that growing might move it in memory (realloc) which you can't due to self references... So you would need the size of the generator when generating it. Which could somewhat be possible but not really with current rust features, i.e. it would need a lot a special care.
- bfrog 6y agoSounds like a recipe for random stack overflows