4 ms·
Also, C++ allows you to be explicit about things. Like std::unique_ptr<> that does not have to count references and guarantees at compile time that: * There wi
by UkrainianJew 4y ago
Also, C++ allows you to be explicit about things. Like std::unique_ptr<> that does not have to count references and guarantees at compile time that:
* There will be not more than 1 reference to the object at any time.
* The object will be deleted once the reference dies.
That's a zero-overhead GC that is enforced at compile time.
And that is the main appeal of C++. You can get close-to-optimal instruction-level behavior while still describing things at reasonably high levels of abstraction. Yes, it has a hell of a learning curve, but once you master it, you can beat any other language out there.
- vvanders 4y agounique_ptr doesn't have any aliasing guarantees, unique_ptr::get() will happily hand out references to the interior pointer. It does give you non-ambiguous ownership semantics which is a good thing but there's still plenty of ways to misuse/abuse it. That said if you can make the aliasing guarantees(such as Rust's borrow checker does) that opens up the possibility of automatically applying restrict semantics[1] which enables further set of optimizations available to the compiler. [1] https://en.cppreference.com/w/c/language/restrict https://en.cppreference.com/w/c/language/restrict
- zamalek 4y agoThere's a lot of UB in that spec. Are compilers capable of warning/erroring UB in this case?
- maleldil 4y agoHow is std::unique_ptr different from Rust's Box? Everything you said applies to Rust. Also, I definitely would not call std::unique_ptr (or Box) a GC.
- steveklabnik 4y agoThey’re the same at a high level, but when you get into the details, there are different. A famous one is that uniq_ptr can’t be passed in registers (mentioned upthread) for ABI reasons, but Box doesn’t have that restriction. Another one is what happens when you move a value out, in C++ it’s in an “indeterminate state”, but in Rust you can’t access a value after move. Which means that you can get a null pointer exception in C++, but not in Rust, and means that destructors for uniq_ptr have to check for this case, whereas in Rust they don’t.
- maleldil 4y agoI understand that. I was talking about the high-level idea of using RAII to manage memory. Parent was talking as if that was unique to C++, while Rust also has it and does it better, for the reasons you stated. Rust defaulting to move-semantics and requiring explict copies is one of the best decisions in the language.
- gpderetta 4y agoNote that the ABI issue with trivial types is not a language issue but a gcc/clang backward compatibility issues with their own ABI. A bit of forward thinking could have prevented the issue (like annotating the type when it was first introduced).
- kzrdude 4y ago> That's a zero-overhead GC that is enforced at compile time. You should check out Rust's concept of ownership. The goodness of ownership that is implemented in unique_ptr in C++ exists for every type in Rust.
- Kranar 4y ago>There will be not more than 1 reference to the object at any time. Untrue: auto x = std::make_unique<int>(5); auto& y = *x; // There are now two mutable references to the object represented by x. >That's a zero-overhead GC that is enforced at compile time. It's not zero overhead unfortunately. Because unique_ptr is not trivially movable or trivially destructible, there are numerous optimizations that every current C++ compiler does not perform, for example being able to pass a unique_ptr in a register. unique_ptr is reasonable given C++'s limitations, but it doesn't come close to being as good as Rust's Box, which is genuinely zero overhead and also guarantees that there's only 1 mutable reference to the object at any given time.