Live data from Hacker News

Why should I have written ZeroMQ in C, not C++ (2012)

250bpm.com

131–140 of 170 posts

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#131
post #30

Earlier quoted context omitted.

> there will always be a case where you forget to propagate an error you got Not if the ecosystem supports Result types a la Rust (and others). You don't get to access the return value unless you deal with handling the error first.

> You don't get to access the return value unless you deal with handling the error first. Well, that's exactly what I was referring to. 80% of the time you don't / can't know what to do with the error at a given call site, so from what I could see, either people end up doing nothing and "abandoning" the error (bad) or panicking (worse). It's better to just let the error go transparently so that if someone actually ca…

> Well, that's exactly what I was referring to. 80% of the time you don't / can't know what to do with the error at a given call site

If you're working with a `Result` type, you can pass the wrapped value up to wherever you want to/can handle it. Either way, you have to handle it. And the type checker ensures that you do.

Typed error checking as available in Rust, Scala, OCaml, ReasonML, Swift, Haskell etc, etc is a far, far better solution than exceptions. I've worked on large code bases with both. There's no comparison.

Even Java's checked exceptions are far, far better than unchecked exceptions like C++. People complain, but it's shitty coding practice not to properly handle a function that can throw (and I speak as someone who's done this and gotten badly bit by it a dozen times before I wised up).

If there's absolutely no recovery possible from an error, then yes, an exception may be acceptable. Otherwise, error values, which can be type checked, are the way to go if offered in your language.

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#132
post #129
post #23

Earlier quoted context omitted.

The google style guide says “ On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code...” and they use a lot of existing code.

> they use a lot of existing code. Doesn’t everyone? Lots of C++ code is not exception safe, including large libraries such as Qt. If I’m writing code that uses such a library, would it be better to take Google’s approach and avoid using exceptions myself, or try to “wrap” the non-exception-safe library somehow?

There is no single answer to that — depends on the library and how you use it. But if it’s not exception safe it’s not exception safe.

There is no way to tell if a constructor failed without catching an exception.

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#133

Author asserts that "The decoupling between raising of the exception and handling it, that makes avoiding failures so easy in C++, makes it virtually impossible to guarantee that the program never runs info undefined behaviour." (and all the woes he encounters afterwards stems from trying to avoid exceptions due to that assertion). But that is not my experience at all. Exceptions are much more reliable than error cod…

ZeroMQ is a library to be called from other languages. You do not want to ever accidentally throw an exception from C++ to a function that is called from outside C++.

That’s fine, the library can catch exceptions at the boundaries of the C API. That’s still usually going to be a lot less tedious than manually propagating error codes all over the internals of the library.

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#135

Earlier 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…

Huh, I didn't know about catch_unwind. Very cool

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#136

Earlier quoted context omitted.

nanomsg was abandoned? I know the previous maintainer moved on to nng, but no one is maintaining it now?

I don't know. Maybe it's not abandoned and maintained by someone. I was using the word loosely as in "focus has moved to nng" and it makes little sense to use nanomsg for a new project at this point. In my experience, if the core contributor moves on and it's not a company, it's only a matter of time before it's fully abandoned. Better to get away from it soon ;)

But gdamore is still maintaining nanomsg https://github.com/nanomsg/nanomsg/commits/master.

gdamore took over from sustrik a long time ago.

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#137

Earlier quoted context omitted.

Well, rarely done isn't the same as never done. docs.rs has exactly the tradeoffs the parent comment is talking about: we have a long-running daemon thread that uses `catch_unwind` and builder threads that occasionally panic. We've had [issues with memory leaks]( https://github.com/rust-lang/docs.rs/issues/656 ) in the past - they weren't related to unwinding that I know of, but it's still possible that they were. Ho…

The solution for docs.rs is handling errors correctly and not panicing.

I was going to talk about some panics we've had recently, but those will hopefully be fixed soon so I don't think that quite fits my message. Instead I want to talk about why 'handling errors correctly and not panicking' wouldn't work in general.

In order for that work, we'd have to have 0 panics - not just few, but none. That requires none of our code to panic, none of our dependencies to panic, and none of our uses of the standard library to panic. If you gave me a limited time frame to run the server - say a week - I think it's possible to make docs.rs that robust. However, for a server that's meant to run 24/7 for weeks on end, I just don't think that's realistic.

What `catch_unwind` lets us do is localize panics to a single web request or crate build instead of it affecting the whole server. Of course we don't want to have 500s for any user, but we _especially_ don't want the whole server to be down until a team member has time to ssh in and restart it manually.

Of course, after that there's whole question of whether making the server that robust is a good use of time in the first place. Is it better to fix a few 500s every week or to fix long-standing bugs? I don't think it's clear that the 500s are more important if they don't affect many users.

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#138
post #22

1. That "C equivalent" for error handling is not an equivalent at all. If one could handle the error in the same function then there is no reason to throw. The "C equivalent" is returning an error code, which has other problems. 2. One can handle errors in initialization without exceptions and half-initialized objects: Make your constructor private and expose a static member function that returns an optional (where T…

> 2. One can handle errors in initialization without exceptions and half-initialized objects: Make your constructor private and expose a static member function that returns an optional (where T is the given class). This comment criticizes an article written in 2012 about a project developed starting in 2007 for not using a technique that debuted in the 2017 edition of ISO C++. For projects that could force all consum…

[deleted]

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#139
post #103
post #29

Earlier quoted context omitted.

I haven’t written anything nontrivial in C++ for many years and so far have only learned and used a couple minor features newer than C++11. Would you be kind enough to point to some resources on why C++17/20 are “powerful and expressive systems programming languages that aren’t like the object-oriented messes of old”?

I wrtote a reply to this question in a comment parallel to yours. In addition: I don't write many classes in the sense of the Gang of Four book. I do write classes that are really just ways to speak with the type system, e.g. a "class" that has one instance variable that is an integer, so takes up only as much space as a native int, yet perhaps acts a special kind of table index. Sequence manipulation, auto, and dest…

Thanks!

Re: Why should I have written ZeroMQ in C, not C++ (2012)

#140

Earlier quoted context omitted.

The solution for docs.rs is handling errors correctly and not panicing.

I was going to talk about some panics we've had recently, but those will hopefully be fixed soon so I don't think that quite fits my message. Instead I want to talk about why 'handling errors correctly and not panicking' wouldn't work in general. In order for that work, we'd have to have 0 panics - not just few, but none. That requires none of our code to panic, none of our dependencies to panic, and none of our uses…

Look how Erlang handles this. Crashing on error is the encouraged policy. A managing process will notice a crashed process and restart it.

Basically crashing is the safe way to release all resources in a problematic situation, at the cost of terminating the process. It's easy when you don't have shared resources at all (Erlang's case), and harder with threads: one threads crashes and frees its resources, another tries to use a shared resource already deallocated. If this can be avoided, life becomes vastly easier, at the cost of higher resource consumption.

Post reply on HN