5 ms·
I can't reply directly to your other comment, so I'll do it here. In the case of pet-graph, I wouldn't say it has large amounts of unsafe (I reviewed it recentl
by bluejekyll 9y ago
I can't reply directly to your other comment, so I'll do it here. In the case of pet-graph, I wouldn't say it has large amounts of unsafe (I reviewed it recently b/c I might start using it), but it does use unsafe. Most data structures in Rust require unsafe for performance or memory access patterns. In these cases the developer is the one responsible for guaranteeing that it is safe (no loss over an unsafe language).
> modern C++ is much safer than unsafe rust
This is an interesting comment. I can't say if you are right or wrong, but it's thought provoking. So I'll quote the rustinomicon here:
Unsafe Rust is exactly like Safe Rust with all the same
rules and semantics. However Unsafe Rust lets you do
some extra things that are Definitely Not Safe.
The only things that are different in Unsafe Rust are
that you can:
-Dereference raw pointers
-Call unsafe functions (including C functions, intrinsics, and the raw allocator)
-Implement unsafe traits
-Mutate statics
Point being Rust doesn't just throw out all the rules. But it's a very interesting assertion.
https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html
- Const-me 9y ago> I can't reply directly to your other comment Next time just wait 5-10 minutes. > Most data structures in Rust require unsafe for performance or memory access patterns. And when I want to compose 2 data structures into my own higher-level one, for performance and memory access patterns I need these two lower-level structures to expose unsafe stuff at their API boundaries. The data structures I saw don’t do that, they’re designed to be consumed from safe Rust instead. > Rust doesn't just throw out all the rules I think in modern C++, with these iterators and smart pointers, you’re less likely to screw up dereferencing a wrong pointer.
- pcwalton 9y ago> And when I want to compose 2 data structures into my own higher-level one, for performance and memory access patterns I need these two lower-level structures to expose unsafe stuff at their API boundaries. The data structures I saw don’t do that, they’re designed to be consumed from safe Rust instead. Can you give a specific example of something you want to do that you can't? > I think in modern C++, with these iterators and smart pointers, you’re less likely to screw up dereferencing a wrong pointer. I don't think this is empirically true relative to C, but even if it is, use after free is still far too common in C++ code.
- Const-me 9y ago> Can you give a specific example of something you want to do that you can't? Compose a hash map + linked list into an LRU cache. Rust how has that in standard library, but they had to implement their own linked list for that. In C++ it’s just a few lines of code, because standard maps+lists compose just fine. Or (more generic example and thus harder to put in the standard library), add an index to existing collection. I have a large collection of some values. I want to build an index allowing to lookup values by some key. Values are not small, can’t afford duplicating them. If you’ll tell “just move values into a hashmap”, my response is “and I also want another, different index of the same set of values by different key”. Again, very easy in C++, encapsulate both the original collection, and a hashmap from key to value pointer. > use after free is still far too common in C++ code. In my experience, use after free = instant crash in debug build. Quite easy to detect and fix.
- burntsushi 9y agoUse an Rc? If you can't afford the reference count, then use unsafe/raw pointers, which it sounds like you'd do in C++ anyway.
- Const-me 9y ago> then use unsafe/raw pointers Even if I manage to extract an unsafe pointer from that Rust collection, I don’t know for how long will it work. For C++ collections, iterator invalidation rules tell me that.
- burntsushi 9y agoYou'd have to box your values. And if you didn't want to do that, then I'd just used the indexing method mentioned elsewhere in this thread. I've used such things in performance critical code.
- Const-me 9y ago> the indexing method mentioned elsewhere in this thread https://news.ycombinator.com/item?id=15180649 https://news.ycombinator.com/item?id=15180649
- burntsushi 9y ago> And when I want to compose 2 data structures into my own higher-level one Could you give a specific example please? I compose data structures in Rust all the time.
- Const-me 9y agohttps://news.ycombinator.com/item?id=15180500 https://news.ycombinator.com/item?id=15180500
- bluejekyll 9y agoMore like 20 it seems ;) > I need these two lower-level structures to expose unsafe stuff at the API boundary Two thoughts: 1) I think you can always use unsafe to get access to a raw pointer (I honestly don't use unsafe often) 2) you need someway to express ownership between both data structures, this can be annoying, no doubt. > C++, with these iterators and smart pointers Does that make it safer than unsafe Rust? Maybe, but there's a lot less unsafe Rust even in these graphs...
- dikaiosune 9y agoIf you click directly on the time of a comment, it's a link to a direct reply page.
- Const-me 9y ago> I think you can always use unsafe to get access to a raw pointer I’m not sure about that. Also I don’t know for how long will it work, C++ has iterator invalidation rules. > you need someway to express ownership between both data structures Not every relation is ownership. Graph modes don’t own each other, an external index doesn’t own the indexed items, etc.
- oconnor663 9y agoI'm really not sure, but I think there's a miscommunication about raw pointers in this thread. I think other folks are suggesting that you can solve the container composition problems you're talking about by inserting raw pointers into a HashMap. But I think you're reading that as obtaining raw pointers to the storage that a HashMap owns, which is why you're worried about iterator invalidation rules and stuff like that? (My understanding is that any reference into storage that a container owns is / could be completely invalidated by any &mut operation on that container.)
- Const-me 9y agoTo create an external index for the existing collection, I need to get pointer of the item stored in that existing collection, compute a key, and put both into the HashMap<tKey, tValue*> So, I need to do both. And also, I need to know when these pointer expire so I can rebuild my index when it happens.