5 ms·
Rust is quite explicit about allocations and reallocations. This makes the language slightly harder to use and increases it's verbosity, but on the plus side th
by estebank 6y ago
Rust is quite explicit about allocations and reallocations. This makes the language slightly harder to use and increases it's verbosity, but on the plus side the behavior of the code is always predictable and the compiler will catch uses that in another language but be accepted and suggests the correct incantation. Rust won't choose between static or dynamic dispatch for you, the code you wrote does.
I think this is the right approach for a performant language and a good compromise in usability. The only thing missing would be to have lints letting you know when using other constructs would be a better trade-off, like switching from dynamic dispatch to static dispatch when there's only one possible caller.
- jcelerier 6y ago> Rust is quite explicit about allocations and reallocations. gotta explain what's the difference between let mut vec = Vec::new(); vec.push(1); vec.push(2); vec.push(3); // likely allocates one, two, or three times and auto vec = std::vector<int>{}; vec.push_back(1); vec.push_back(2); vec.push_back(3); // same
- Arnavion 6y agoYeah, I'm really confused by the two subthreads saying Rust doesn't have hidden allocations. The standard library is full of them, and even with `no_std` there is the possibility of a "global" allocator (GlobalAlloc) to be able to do hidden allocations without an explicit allocator. Box, Vec, etc rely on that even in `no_std` code. The only way to have explicit allocations in Rust is to not use libstd (but this isn't special in the context of writing OSes anyway) and disallow using the GlobalAlloc trait, as well as any third-party libraries that rely on it. Unfortunately both the explicit allocator LocalAlloc and the global allocator GlobalAlloc, as well as all the types that rely on GlobalAlloc, are defined in the same library liballoc, so keeping one and removing the others requires patching liballoc. As far as other non-C languages go, Zig has an explicit allocator that neeeds to be threaded through any function that wants to allocate, which would likely satisfy Linus's requirement.
- deleted 6y ago[deleted]
- kbenson 6y agoCan't you just as easily do the same in C with functions and a struct? If so, I have to imagine Linus is referring to something different (I thought it was generally about things like copy constructors where what's going on is more hidden and possibly complicated than an assignment would naively indicate). Then again, I don't commonly use any of the languages in question, so maybe I'm missing the point entirely.
- a1369209993 6y agoThey're not talking about that - you could do: struct vec_int vec = VEC_INT_EMPTY; vec_int_push(&vec,1); vec_int_push(&vec,2); vec_int_push(&vec,3); even in C. They're talking about things like: Foo foo; // Foo::Foo allocates z = x + y; // operator+ allocates w = x; // operator= allocates foo += *bar; // operator* allocates Rust can do most of those things, but it's not encouraged and significantly less pervasive, especially in the kind of code you'd want to use in a kernel in the first place.
- pjmlp 6y agoSo it can, case closed. Being encouraged or not, doesn't control the hands of those typing the code.
- unionpivo 6y ago> So it can, case closed. Being encouraged or not, doesn't control the hands of those typing the code. Sure in theory. But in practice most consider such a behavior a code small or straight bug an d fix it. So there is a difference in practice.
- pjmlp 6y agoIn theory every expert level C developer writes correct code, in practice errors happen.
- estebank 6y agoThe gp is slightly incorrect: in Rust you cannot override the constructor so that it allocates more than the struct itself. You can extend + and allocate in it, which is why it is treated in theory and practice as if it were a method call, because it is. You cannot override the assignment operator, it will always be either a conceptual move of ownership or a memcopy at worst, never a method call with any arbitrary number of heap allocations. Same for the dereferencing operator, it cannot be overriden. This is the reason we say there are no hidden allocations in Rust. In every language you might have allocations in a method call. Some languages consider assignment to be one for example, Rust doesn't.