Live data from Hacker News

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

250bpm.com

101–110 of 147 posts

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

#101
post #69
post #48

Earlier quoted context omitted.

C with classes is undervalued, and templates are overvalued, IMO. Just switching compilers makes the C code more robust.

Templates are the main thing in C++ that you can easily use everywhere with zero costs in compatibility. And they certainly beat C's "equivalent", macros.

You can use macros with C++

That's what wxWidgets did since forever, and to the dismay of C++ purists, I find their code easier to read than most templates.

Not to mention it compiles much faster.

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

#102
post #93
post #72

This seems to be a failure to understand when exceptions and when error codes are to be used. I'm just starting a big infrastructure project that needs to be high uptime and distributed across a large number of machines, and I'm doing it in C++ because I know I'd never get it working in anything else. Let's take one specific example -- connecting to a remote host. The loop that goes through the DNS returned IP number…

I think you are right about the author not understanding exception handling very well. But your handling of exceptions is also incorrect. In a fault-tolerant system, dns lookup failures or repeated connection attempt failures is something you design for -- they are not exceptional events. E.g you have function called connect() then it should return something like a state object with a connection instance or an error…

I disagree -- the determinant is about state management and locality of error handling and this is all about how your code is structured, not whether the error is expected or not in some nebulous sense.

If you can handle the connect failure locally (i.e. probably no further away then caller of the connect function) then by all means do so. If you find another structure in your code makes other things simpler, but no longer allows you locality of error handling you should use an exception.

Well designed libraries allow you to choose. Check out Boost.ASIO for an example of this. Every API has both an exception and error handling version and you're free to use whichever is most appropriate for what you're trying to achieve.

This whole thing about 'expected' and 'unexpected' errors is a red herring that leads people down the wrong path.

The exception backs you out of the transaction that your code is performing -- this is the way to think about it. An error code allows you to try something else whilst keeping the transaction alive. Which you use depends not at all on whether you think the error is "normal" or not.

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

#103
post #72

This seems to be a failure to understand when exceptions and when error codes are to be used. I'm just starting a big infrastructure project that needs to be high uptime and distributed across a large number of machines, and I'm doing it in C++ because I know I'd never get it working in anything else. Let's take one specific example -- connecting to a remote host. The loop that goes through the DNS returned IP number…

Yeah, it's a nice example. However, I disagree on the severity of your prognosis.

In C (my preference over C++) I would use an arena memory allocation strategy in this case. This is something I learned from reading the python interpreter source code: when your parser barfs way down in the call stack, an arena is a simple way to clean up everything. (I'm not saying it will be easy in your particular case.)

As for exceptions, you can just use the return value to signal an exception, or if you want to be a bit more radical, use a longjmp.

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

#104
post #72

This seems to be a failure to understand when exceptions and when error codes are to be used. I'm just starting a big infrastructure project that needs to be high uptime and distributed across a large number of machines, and I'm doing it in C++ because I know I'd never get it working in anything else. Let's take one specific example -- connecting to a remote host. The loop that goes through the DNS returned IP number…

Yeah, it's a nice example. However, I disagree on the severity of your prognosis. In C (my preference over C++) I would use an arena memory allocation strategy in this case. This is something I learned from reading the python interpreter source code: when your parser barfs way down in the call stack, an arena is a simple way to clean up everything. (I'm not saying it will be easy in your particular case.) As for exce…

The slab allocator is a great strategy, but of course only works for memory, which is really a special case of one out of all of the resources we want to manage. If you're writing long running processes you need to care about any number of file descriptors, maybe mutexes, certainly locks.

You can't bypass all of this in all cases assuming that you only need to deallocate memory. Destructors tidying this up as the exception unwinds the stack is extremely easy to reason about and stops any number of idiotic mistakes.

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

#105
Author of the article here. Everything said in the article still applies IMO but, to be fair, C misses some useful modern features, most importantly a decent concurrency support. I've recently tried to remedy the problem by implementing Go-style concurrency in C: http://libmill.org

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

#106
post #24

Earlier quoted context omitted.

While it works, it would be better if multiple return types were supported natively by the C++ language precisely because of this: #ifdef _WIN32 # ifdef EXPORTING # define DECL __declspec(dllexport) # define STORAGE # else # define DECL __declspec(dllimport) # define STORAGE extern # endif #else # define DECL # define STORAGE #endif // For every return tuple type actually used: STORAGE template class DECL std::tuple…

That's not a C++ issue, it's a Windows issue (which is why DECL and STORAGE are defined to nothing on anything other than Windows).

It's precisely a C++ issue because if multiple return types were natively supported by the C++ language, none of this would be needed since no one would be trying to export a STL object across shared object (or DLL) boundaries.

It's only the workaround (tuples) of this C++ issue that platform-specific issues are allowed to arise, like Windows as you observed, which is why I view the platform-specific issues as symptoms of a deeper problem.

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

#107
post #102
post #93

Earlier quoted context omitted.

I think you are right about the author not understanding exception handling very well. But your handling of exceptions is also incorrect. In a fault-tolerant system, dns lookup failures or repeated connection attempt failures is something you design for -- they are not exceptional events. E.g you have function called connect() then it should return something like a state object with a connection instance or an error…

I disagree -- the determinant is about state management and locality of error handling and this is all about how your code is structured, not whether the error is expected or not in some nebulous sense. If you can handle the connect failure locally (i.e. probably no further away then caller of the connect function) then by all means do so. If you find another structure in your code makes other things simpler, but no…

Well, the reason exceptions should be reserved for exceptional cases is because they are gotos. There is no way around that, a function that both returns values and throws exceptions is more complex than one that doesn't because you are jumping through call frames.

I once worked with a billing system that threw a BillingException when a charge didn't go through. It works ok, as long as your only response to such an error is to spew an error message to the user. But the more you need to handle it, the less an exception makes sense. The code that tried to handle the BillingException was a tangled mess of try and catch statemetns mixed with retry loops. For example, if there was a temporary error at the payment provider, you would just retry a few times, a permanent error, try with another account, if the customers remaining funds were to low show an error message or if they were just a few dollars of, charge them that and be happy we got something from them.

On the other hand, the billing system could also throw a DbException in case there was something wrong with the database connection. That's a different kind of problem and fatal for a database-backed website. Nothing to do, except log the error and crash.

The point of exceptions is not so much that you can catch and handle them, but that it separates exceptional situations from in-band normal error handling. Now what is in-band and what is exceptional depends on the circumstances which is why, as you say, Boost.ASIO provides both variants. If your system is supposed to handle the errors, use the one without exceptions. If not then use the one with exceptions.

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

#108
post #67

I like Google's guidelines for writing C++. I've worked in a number of groups that independently came up with just about the same subset of C++ (and same set of styles), so those guidelines aren't totally off the wall.

The Google guidelines are... somewhat out of sync... with the intended use of language features as described in the Standard and the recommendations of people associated with it. They seem to take as a starting assumption that the language is misdesigned and major parts of it should simply be avoided or used in unintended ways. If you agree, it's a perfectly fine guide. Otherwise, I'd recommend reading any of Scott M…

I've read those books. I have a lot of respect for the authors, and they have a lot of good advice.

But Exceptional C++ made me not want to deal with C++ exceptions, ever. If getting C++ code correct in the face of exceptions is that bloody hard, then the language is broken. I'm convinced that cobbling up an "int" equivalent type that is exception safe is a pyrrhic endeavor that will be a continual source of fragility in production code.

Alexandrescu's Modern C++ Design made me want to forget that templates ever existed. The entire second half of that book I kept saying to myself, "If I'm on a project with someone actually checking stuff like that in, one of us is going to have to leave." Fortunately I've yet to run into those kinds of template metaprogramming games in the wild. Good programmers seem to abhor them.

[Edit: Actually, I remember a bunch of stuff in Modern COM that used templates very heavily. Essentially impervious to debugging; that stuff sucked hard]

More recent C++ design decisions are better than the ones the committees made in the 90s and early 2000s. But the successful teams I've seen all practice restraint and keep things debuggable by limiting the amount of magic going on under the hood, regardless of what the committees have been pushing.

The Google C++ standards (and others that were independently created and haven't been seen much outside their own development cultures) may be "dated", but they remain an indictment of the design of C++.

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

#110
post #8

Earlier quoted context omitted.

If you read part II (the link to it is near the end of the post), you see that one of the things he wanted was intrusive linked lists. From what I have read so far, implementing intrusive lists is not easy in Rust. (If you know of a working intrusive doubly linked list implementation in Rust 1.0 that does not invoke undefined behavior, please tell me; I'd like to know how it should be done.)

Do you mean "unsafe" instead of "undefined"? Here's what I found after a Google search, by one of the core Rust devs (unsurprisingly). https://github.com/pcwalton/multilist

No, I really meant undefined: http://doc.rust-lang.org/stable/reference.html#behavior-cons...
Post reply on HN