2 ms·
I mean, it's possible to write bad code in C++. But at least it's possible to write good code too. C++ makes a careful sequence that's hard to get wrong and eas
by o11c 3y ago
I mean, it's possible to write bad code in C++. But at least it's possible to write good code too. C++ makes a careful sequence that's hard to get wrong and easily compiler enforced:
* if a given subobject (field or base class)'s constructor runs, its destructor is guaranteed to run.
* in particular, in low-level ownership classes, you can arrange for field initializers to be `noexcept`, so you get to run their dtor, regardless of subsequent manipulation of the fields - just be sure to not assume invariants from the fully-constructed main object case. In most classes, deferring all ownership logic to the fields is simpler - rule of zero beats rule of 5. And if you do add manual try-catch during construction it will actually work.
Languages other than C++ generally fail in several ways:
* Allow exceptions to be thrown by the runtime for reasons unrelated to the code being executed
* No support for subobjects, forcing all objects to be allocated separately and thus the runtime not knowing it needs to poke them since finalizers are only applied to objects not pointers. In particular, Python's `contextlib.ExitStack` can narrow the window in which case leaks are possible, but not eliminate it.
Rust does slightly better than C++ by enforcing trivial moves, at the cost of making many useful programs impossible to write.
- worik 3y agoOuch! > Rust does slightly better than C++ by enforcing trivial moves, at the cost of making many useful programs impossible to write. What "useful" programs fit a useful definition of "many"? It makes self referential looped data structures hard to write (double linked lists, trees with pointers to parents). No loss. Great improvement to have fewer of those It makes arbitrary allocation hard. Enforces behaviors. Makes a programmer think very hard. "useful programs impossible to write. " No it does not. It ,ages a lot of bad ideas hard to implement, makes nothing "impossible "
- o11c 3y agoGood luck implementing "peer pointers" in Rust. Zero allocation involved, trivial to do safely in C++. class A { /* can be NULL if detached */ B *peer; /* other fields generally exist in one of the classes. */ /* useful objects are typically created in pairs, but can be constructed detached if needed */ /* move ctor and swap keep the (value) objects pointing at each other */ /* move assignment and dtor call detach() on the overwritten/expiring object */ /* Often separate "detach and cancel" and "detach without canceling" are useful */ void detach(); /* other functions specific to the peerage */ }; class B { A *peer; /* same API as `class A`, but usually most of it is only used via one owner. */ /* In my experience, generally one class's instance goes in some collection of centralized objects like an event loop, and the other is used as a handle to it. */ }; I guess we could always use the usual Rust solution of "screw ownership and efficiency, just shove everything in an `Rc<RefCell<>>`".