4 ms·
This is really exciting, and clearly more powerful than what you get in C/C++. That being said: >In a language like C++ there’s only once choice in this situa
by hoodedmongoose 11y ago
This is really exciting, and clearly more powerful than what you get in C/C++. That being said:
>In a language like C++ there’s only once choice in this situation; that is to clone the vector.
What about a shared_ptr to the vector?
- imron 11y agoDoesn't help, because you don't necessarily know when the other shared pointer could push something to vector, potentially reallocating the internal array and thereby invalidating any references you had to the contents of the vector.
- hoodedmongoose 11y agoAh okay - I didn't realize rust was guaranteeing that no one else would _modify_ the vector while an instance of that struct was around. That's pretty cool.
- imron 11y agoIt's very cool. Rust guarantees that at any point in time there will only be one part of the code that can modify the contents of some data, and will fail to compile if it detects a situation where this is not the case.
- Manishearth 11y agoRust follows multiple-readers or single-writer even in single-threaded situations. You can hold multiple immutable references to an object, or a single mutable one. Initially this gets annoying, but as time passes one realizes how awesome this is. It prevents iterator invalidation (and vector-move-invalidation), for one (it's also necessary to get memory safety for our ADT enums since you can otherwise change the variant and invalidate a reference to its contents). In general you realize that in a large codebase, it's almost as bad as a multithreaded situation -- you don't know what objects are being modified by the methods being called and the code is too large to easily figure it out.
- coherentpony 11y agoOr scoped_ptr to transfer ownership. There's certainly more than one choice, though.
- imron 11y agoNot really, and I say this as a fan of C++. These things protect against one part of the problem - deletion of the vector, but not the other part - mutation of the vector, causing a new internal allocation, and leaving references to any elements of the previous vector invalid. It's possible to make sure this isn't happening in C++ if a) your code base is small enough and b) you are careful, but the point of the article is that with Rust, you can make the changes and be confident that the compiler will fail if you do anything dangerous. With C++, you can make the changes and through careful checking be reasonably confident everything works (perhaps only to find out later that you were wrong). It's very different from having the compiler verify that you are not doing something unsafe.
- Manishearth 11y agoI couldn't have moved the vector, it was being used elsewhere.
- adwn 11y agoA shared_ptr does not prevent iterator invalidation caused by reallocation, because the pointed-to vector is not locked, or in any other form stopped from being modified. In Rust, when you have an immutable reference to a memory location, you know for certain that it won't be modified by distant code as long as you hold the reference. This guarantee also allows more compiler optimizations, because v[5] has the same value after a function call as before.
- hoodedmongoose 11y agoThanks for the explanation, I missed that!
- Manishearth 11y agoRemember that this was an API, exposing the `&[Attributes]` to external consumers. I may not want to hold pointers to the insides, but a consumer of the API might. Also, iterator invalidation. Also, runtime overhead of shared_ptr. (I added a footnote to the post to explain the issues with shared pointers)