I think there's a lot of merit to this post, but it really shows its age. Modern C++ typically suffers from only the last point raised - exceptions during destruction, but that goes against the all good C++ practices. Overall, the author's approach to exception use is flawed. It's bad form to use exceptions for code flow purposes, as per their example. If you throw an exception in the same block that catches the exce…
Why should I have written ZeroMQ in C, not C++ (2012)
51–60 of 170 posts
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#52Earlier quoted context omitted.
> 3. Throwing in destructors is not a C++ problem, it's a general semantic problem around resources that aren't guaranteed to be freed up successfully. They are a pain in any language and you can only do best-effort approaches for not leaking them. C++ is quite good here, arguably quite better than Rust, since in C++ you can add a `noexcept(true)` clause to your destructor, and if it throws, your program terminates.…
I am not sure what you mean here. "throwing in a destructor", aka "panic during Drop" in Rust terms, runs the risk of seeing "thread panicked while panicking. aborting." In general, Rust treats panics as being something that terminates execution, not something for error handling. Where are you seeing these memory leaks in Rust code?
impl Drop for Foo {
fn drop(..) {
self.cleanup();
self.free_memory();
}
}
even if `self.cleanup()` panics. When that happens, `self.free_memory` will never be called, and memory will be leaked if `panic=unwind`, which is the default behavior. If there is a `catch_unwind` somewhere, these leaks will grow over time.The same code in C++:
~foo() {
this->cleanup();
this->free_memory();
}
does not have this issue, because if `this->cleanup()` unwinds, that unwind makes `~foo` abort, because `~foo` is `noexcept(true)` by default.In Rust, one cannot make `Drop::drop` be "nounwind", so to emulate C++'s behavior, one needs to write:
impl Drop for Foo {
fn drop(...) {
if let Err(_) = cath_unwind(|| {
self.cleanup(); self.free_memory();
}) {
abort();
}
}
}
or use a `DropGuard` to make sure that `self.free_memory()` is called if `self.cleanup` throws, etc.Destructors being fallible are very weird things. In C++, destructors are infallible (at least by default). Rust supports fallible destructors, with all its cost (every time an object is dropped, doing this can fail, adding another "return" point from your function), yet minimal or zero value.
At least, I couldn't find any examples in the Rust book / reference / rust-by-example that show in which situations unwinding from a destructor is a good thing to do.
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#53I'm a bit confused about the current state of ZeroMQ and its relatives. There's nanomessage, which for some reason didn't pan out and is superseded by nng(?), but ZMQ still seem to be the most popular option. If I were to pick a broker-less message queue today, what should I pick?
My understanding: Pick zmq if you want something safe and battle-tested with good client library support. Pick nng if you want to be at the forefront of new tech or need some of its unique features over zmq ( https://nanomsg.org/documentation-zeromq.html ). Performance-wise nng still seems like it's inferior to zmq because it's not as heavily optimized. There are lots of performance-related unresolved Github issues.…
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#54Re: Why should I have written ZeroMQ in C, not C++ (2012)
#55By now he probably realizes that the Java version is what he was looking for all along: https://github.com/zeromq/jeromq Why C/C++ coders don't even write "Hello World" in Java SE before drifting away into rewriting the ball bearing (1907) part of the wheel is beyond me. The Throwable class is exceptional in every way, it wastes almost nothing and gives the programmer the ability to catch all problems that occur in t…
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fae709d4a10, pid=18032, tid=140386298201856
#
# JRE version: Java(TM) SE Runtime Environment (8.0_60-b27) (build 1.8.0_60-b27)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.60-b23 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V [libjvm.so+0xa8aa10] Unsafe_SetNativeLong+0xf0
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
#
# /opt/production/hs_err_pid18032.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#Re: Why should I have written ZeroMQ in C, not C++ (2012)
#56I was trying to figure out if this was satire. C++ gives you strictly more tools, particularly for guaranteeing reliability, and they're all optional. What particularly laughable here is the split ctor/init pattern is allegedly driving them towards C, whereas C doesn't even give you dtors! If you're forgetting your init calls, are you really telling me you're not going to forget your destructor call? There are plenty…
> C++ gives you strictly more tools, particularly for guaranteeing reliability, and they're all optional. You are right. But it doesn't help. When I used C++, I constantly shot myself in the foot by using its features. It did not feel like overusing, but I just wanted type-safety and to replace macros. It was impossible to restrict to useful features, because they are all useful in their way, only they come at the pr…
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#57I was trying to figure out if this was satire. C++ gives you strictly more tools, particularly for guaranteeing reliability, and they're all optional. What particularly laughable here is the split ctor/init pattern is allegedly driving them towards C, whereas C doesn't even give you dtors! If you're forgetting your init calls, are you really telling me you're not going to forget your destructor call? There are plenty…
> C++ gives you strictly more tools, particularly for guaranteeing reliability, and they're all optional. You are right. But it doesn't help. When I used C++, I constantly shot myself in the foot by using its features. It did not feel like overusing, but I just wanted type-safety and to replace macros. It was impossible to restrict to useful features, because they are all useful in their way, only they come at the pr…
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#58I think there's a lot of merit to this post, but it really shows its age. Modern C++ typically suffers from only the last point raised - exceptions during destruction, but that goes against the all good C++ practices. Overall, the author's approach to exception use is flawed. It's bad form to use exceptions for code flow purposes, as per their example. If you throw an exception in the same block that catches the exce…
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#59Earlier quoted context omitted.
I am not sure what you mean here. "throwing in a destructor", aka "panic during Drop" in Rust terms, runs the risk of seeing "thread panicked while panicking. aborting." In general, Rust treats panics as being something that terminates execution, not something for error handling. Where are you seeing these memory leaks in Rust code?
In Rust, this destructor is perfectly fine: impl Drop for Foo { fn drop(..) { self.cleanup(); self.free_memory(); } } even if `self.cleanup()` panics. When that happens, `self.free_memory` will never be called, and memory will be leaked if `panic=unwind`, which is the default behavior. If there is a `catch_unwind` somewhere, these leaks will grow over time. The same code in C++: ~foo() { this->cleanup(); this->free_m…
https://doc.rust-lang.org/edition-guide/rust-2018/error-hand...
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#60Earlier quoted context omitted.
...and now you know what a "factory method" is.
Almost. One of the biggest advantages of a class factory is that it can return a pointer to an interface rather than a concrete class.