This article is simultaneously both obsolete and completely current. Obsolete in that the C++ committee has addressed almost all of the issues raised (e.g. constructor semantics, xception semantics et al) though the discussion of site-of-error/handling-of-error continues unabated. Later versions of C++ (17and 20) are powerful and expressive systems programming languages that aren’t like the object-oriented messes of…
True, I recently returned to C++ after many years absence and I'm thrilled with all the good stuff that has been added BUT it took me quite a while to learn how I'm going to unlearn/relearn my old practices.
Why should I have written ZeroMQ in C, not C++ (2012)
81–90 of 170 posts
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#82Earlier quoted context omitted.
> 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…
Hm, we must read very different Rust code. ? is even easier than a panic. And that search has a ton of false positives: both in general, as well as "unwrap" being the more common way to get a Result to panic.
$ cd servo/components
$ rg -F 'panic!' | wc -l
276Likely a fair amount is justifiable, but things like this ? https://github.com/servo/servo/blob/master/components/script... or this https://github.com/servo/servo/blob/master/components/gfx/pl... ?
that's a really strong code smell (or at least doing a similar thing in a C++ program, e.g. calling abort() / SIGTRAP, would be, even with a signal handler, a really really really long discussion in code review)
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#83Writing in C++ means that the C++ library you are using becomes a dependency. Probably not an issue, if you have the source code to all libraries that you use, but maybe an issue if you are vendor and try to support not only all possible modern compilers, but what they target to (platforms, runtimes, models, etc.) With just "C", not "C" only at the interface part, you can avoid that. Even to the point that your binar…
With "C" there is less to care there, as most is set in stone (unless you use some really compiler vendor specific extensions, that appear during link time).
Just an example - https://devblogs.microsoft.com/cppblog/making-cpp-exception-... - this is great improvement, but also means that if you've compiled your lib with VS2019, and it throws an exception under application that uses VS017 - it'll not work.
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#84I 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…
std::ofstream is a good example. Flushing and closing the file happens in the destructor if not done explicitly. Not being able to throw IO exceptions from the destructor breaks object encapsulation by requiring explicit error-checking. One could argue that it's simply a bad abstraction; an open file handle is not in a fully consistent state and so a C++ object pretending to be valid while representing a file handle may have been a poor choice as opposed to e.g. record-based or transactional IO where writes could be atomically flushed or fail.
In general any objects representing IO can be victims of error conditions in destructors because external state can change unexpectedly between the last valid state of the C++ object and its destruction, especially if the object abstracts away some non-deterministic behavior.
Destructing objects may also require modification of other data structures: Updating special containers or indexes, unregistering from a queue, waiting for thread completion, etc. This can force destructors to eat exceptions that should otherwise be passed up to callers.
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#851. 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…
In a decade using C++, I haven't encountered these problems. I never use exceptions and I do exactly what you suggested in #2: if construction can fail, have a factory method and a private constructor (I use a simple ValueOrError type, rather than optional, to be able to communicate information about the error, though: https://github.com/alefore/edge/blob/876c4328610262b11fda553...).
Cheers!
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#86No, I think high-level static data typing is very important. Today Rust would be a better language than C++ for this, but C++ is still better than C.
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#87Earlier quoted context omitted.
Hm, we must read very different Rust code. ? is even easier than a panic. And that search has a ton of false positives: both in general, as well as "unwrap" being the more common way to get a Result to panic.
c'mon... $ cd servo/components $ rg -F 'panic!' | wc -l 276 Likely a fair amount is justifiable, but things like this ? https://github.com/servo/servo/blob/master/components/script... or this https://github.com/servo/servo/blob/master/components/gfx/pl... ? that's a really strong code smell (or at least doing a similar thing in a C++ program, e.g. calling abort() / SIGTRAP, would be, even with a signal handler, a rea…
And yes, I do think that both of these are pretty justifiable: both of these are effectively assertions, which is not unheard of in C either.
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#88It seems like the author's main complaints are avoided if one follows the Google C++ style guide, which says: - Don't use C++ exceptions - Don't do work in constructors (prefer "Init" or factory functions instead) https://google.github.io/styleguide/cppguide.html There may be other reasons to prefer C over C++, but if you don't like exceptions, you don't have to use them.
> Don't use C++ exceptions That's not what Google's C++ style guide says at all. They only argue that Google's old C++ code base is not exception-tolerant, thus as they don't want to waste time and they don't want risk adding bugs by refactoring their legacy code then they just decided to not use exceptions. That's it.
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#89I 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…
Another way to support RAII without throwing exceptions is to somehow make the error case an explicit configuration of the class with well-defined behavior. For example, in a "File" class with no filedescriptor you could return a defined "error" from any function calls which would require a filedescriptor. Receiving such a return value or return structure would then signal that the File class is not in a working stat…
Re: Why should I have written ZeroMQ in C, not C++ (2012)
#90Earlier quoted context omitted.
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.…
nanomsg was abandoned? I know the previous maintainer moved on to nng, but no one is maintaining it now?
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 ;)