3 ms·
It's unusual to take references to the contents of a unique pointer. There is one idiom which says that if one has a smart ptr and a function taking a ref, the
by blub 9y ago
It's unusual to take references to the contents of a unique pointer. There is one idiom which says that if one has a smart ptr and a function taking a ref, the raw ptr should be passed, but that's it. It's frowned upon... nay scoffed at to store references one receives as parameters, so that temporary ref will go away after the function call, leaving the smart ptr as unique owner.
This should not be a problem and it certainly doesn't make C++ more prone to use after free. Null pointers are the problem.
Both can be solved though by creating e.g. a safe smart ptr which does null checks and only exposes operator->.
- pcwalton 9y ago> It's unusual to take references to the contents of a unique pointer. No, it's not. It happens every time you call a method on the referent (well, OK, this is technically not a reference, but it doesn't matter to the argument).
- blub 9y agoOne is not taking the reference. When writing ptr->foo() the ref is temporary, not accessible and will be cleaned up when the method call on the raw ptr finishes. Taking the reference would be "auto foo = ptr.operator->()". This could be forbidden by not providing op->, and instead having an apply function which takes a method name and the parameters. That would be safer, but probably too much effort for little gain.
- nly 9y agoIf you're calling a method on the object referred to by a unique_ptr, then you won't have a use-after-free because the thing will exist. The only way it wouldn't exist would be if you typed "delete myuniquePtr.get()", which would be dumb. It could be a null unique_ptr of course, but I don't see how this is anything worse than a denial-of-service.
- pcwalton 9y agoNo, you could get a reference to the container of the object and indirectly delete it. For example, if the unique pointer were part of a global std::vector, clearing the vector would invalidate the this pointer. Keep in mind that you are at this point arguing against the existence of actual zero-days that have occurred in Firefox (and lots of other software). This is not a theoretical concern.
- nly 9y agoThis goes back to what I said about using pointers as implementation details. If you put unique_ptrs in to a _global_ then you're doing something stupid already. Just think about it. Why does something that can only be pointed to from one place need to visible globally in the first place? My point is all Rust does is force you stop and think, and while C++ lets you do dumb shit, it's hardly fair to blame the language when almost-safe C++ is actually cleaner and easier to read and write than dumb C++. Build your own handle types with well-defined ownership semantics, use explicit move() sparingly, pass objects by value, use references, utilize the stack and temporaries. Only put pointers inside the guts of classes and your data structure implementations. These techniques go quite far. And Firefox as an appeal to authority is hardly compelling. As another, I've seen bug fixes in Chromium where the original code quality is so poor it was hard to believe it came out of Google. Of course, since then i've learned most C++ out of Google is total crap.