Live data from Hacker News

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

250bpm.com

61–70 of 147 posts

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

#61

Earlier quoted context omitted.

Good luck finding a language out there that doesn't have pitfalls.

To be fair I think most languages don't have pitfalls as defaults in the C++ sense :D

But most languages that have seen prominent use have obscure corners that no one should ever visit.

PHP has absolutely awful parts for example. (Magic Quotes anyone?) Even relatively "clean" languages like Java or C# can be completely mucked around if you abuse reflection or do dumb things (ie: have property getters / setters in C# do something insane... like get {return blah++;} )

I mean, any language that has mutexes (ie: all of them) can more or less lead to absolutely dangerous situations. C++ RAII may not be the best (compared to D or Rust or whatever), but C++ is the most widespread language that has complete RAII support.

If you even learn the most basic of C++ patterns: shared_ptr, RAII destructors... (which are useful concepts in C++'s "replacements" anyway), C++ becomes not only a manageable language... but one of the most widespread useful languages current right now.

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

#62
post #24
post #13

Earlier quoted context omitted.

Multiple return values is now handled in C++ with tuples and std::tie.

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).

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

#63
post #15

Earlier quoted context omitted.

yeah go/rust error handling is great. Much better than exceptions which make the code hard to read since you can't easily predict where is the flow going to jump. And the multiple-return is very convenient in this case too. Also, with Go's approach you have to either explicitly ignore the error or deal with it.

My problem with Go (and I love the language a lot) is that a lot of my error handling is "stop execution in the function and bubble the error up", which results in my code being littered with if err != nil { return err }, which is a bit annoying. If I'm doing something wrong here I'd love to know it.

This annoyed me to no end working in node.js, having to manually re-raise errors at every step is pretty tiresome and error prone (no pun intended).

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

#64
post #6

This might be unrelated, but after reading this 3 years after publication I think that Go approach to error handling i so much better because of exactly the same simplicyty as C. ( If you dont’t understand why, dont’t worry it will be obvious to you in 3 years :-)

>I think that Go approach to error handling i so much better because of exactly the same simplicyty as C. Not to mention Go having multiple return values IMHO also takes away the major pain point of returning errors in C; using up your only return value and having to take pointer arguments when you would rather not.

A common way to solve that is to have a function argument point to a place where you want the result to end up, and always return FOO_ERROR or FOO_OK.

i.e.,

    int foo_new(foo_t **res);
    int foo_mutate_copy(foo_t *foo, bar_t *bar, foo_t **new_foo);
Instead of

    foo_t *foo_new(); // returns NULL on failure
    foo_t *foo_mutate_copy(foo_t *foo, bar_t *bar); // returns NULL on failure
I also like the Go way, just thought this way of doing things in C should be mentioned in the thread.

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

#65
post #54

Earlier quoted context omitted.

And we share 50% of our DNA with a tree... That's not meant to be snarky, but what's is the minimum size of a language spec? I don't know the answer, but I'd think the delta over that would be the better comparison. For example if you can't really spec a language in less than 200 pages then C++'s spec is more like 10 times as big as JavaScript.

Scheme has the smallest (useful) language specs that I know of. For example, R5RS is 48 pages (44 if you exclude the back matter.)

Here is one of the smallest useful (ie. turing complete) language's full specification :

> Subtract and branch if not equal to zero[edit] > The SBNZ a,b,c,d instruction ("Subtract and Branch if Not equal to Zero") subtracts the contents at address a from the contents at address b, stores the result at address c, and then, if the result is not 0, transfers control to address d (if the result is equal zero, execution proceeds to the next instruction in sequence).

This is all of it.

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

#66

Earlier quoted context omitted.

> No, actually, it doesn't. Perhaps less in what features to avoid, but there's plenty of hidden gotchas to avoid in JavaScript still. https://www.youtube.com/watch?v=et8xNAc2ic8 https://dorey.github.io/JavaScript-Equality-Table/ > C++ is a huge language, javascript is a relativly small one. C++'s ISO/IEC 14882:2003 weighs in at 786 pages, compared to ECMA-262 (5.1 Edition)'s 258 pages (measuring by PDF reader). A ~3…

And we share 50% of our DNA with a tree... That's not meant to be snarky, but what's is the minimum size of a language spec? I don't know the answer, but I'd think the delta over that would be the better comparison. For example if you can't really spec a language in less than 200 pages then C++'s spec is more like 10 times as big as JavaScript.

"Number of pages in specification" is a rather useless metric to use to compare languages, since there are so many variables. And not just things like point size or margins or what have you, but the contents themselves vary. Some specifications include an EBNF grammar, others may try to describe it via natural-language rules, and others may just say "see the reference implementation". Some specifications include documentation on the language's standard library (the scope of which is a factor that itself varies greatly from language to language), and some of these will go into differing amounts of detail (e.g. providing upper bounds for computational complexity of algorithms). Some languages will go into great detail about memory models (especially low-level ones), while others will wave it away as an implementation detail.

TL;DR: don't trust anyone who tries to use the length of a specification as a comparable proxy for complexity. I can write a 10,000-page standard for Scheme if you hire me to.

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

#68
post #48

Earlier quoted context omitted.

And so I will continue to avoid C++ because I'm not a master and will not avoid the many pitfals, and I want to get things done, not become a master of C++.

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

Templates can be abused, but there's real value to simple ones such as container classes and even shared_ptr and unique_ptr. The subset of C++ I personally use is pretty small, but I hope I never go back to manual memory babysitting.

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

#69
post #48

Earlier quoted context omitted.

And so I will continue to avoid C++ because I'm not a master and will not avoid the many pitfals, and I want to get things done, not become a master of C++.

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.

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

#70

Earlier quoted context omitted.

My problem with Go (and I love the language a lot) is that a lot of my error handling is "stop execution in the function and bubble the error up", which results in my code being littered with if err != nil { return err }, which is a bit annoying. If I'm doing something wrong here I'd love to know it.

This annoyed me to no end working in node.js, having to manually re-raise errors at every step is pretty tiresome and error prone (no pun intended).

I've recently started working in node after spending some time in Go-land and the reverse applies to me. The code I'm writing is a mix of js + Go and I find that in JS I have no sense for what can go wrong since it's not obvious to me if a method will throw an exception or not. However, with Go it forces me to think about my error path.

I do find littering code with err checks can be annoying and ended up reaching a compromise. For all code that is likely to be part of an externally public package I use 'if err !=' checks. For application level code that will be internal to my application (and internal to the file I'm working in) I use a small library [1] I wrote, that uses the panic-defer-recover style talked about in the Go documents for internal error handling [2].

However, I find that in most situations I usually prefer to not use panic-defer-recover, with if checks providing more clarity.

[1] https://github.com/surullabs/fault [2] http://golang.org/doc/effective_go.html#recover

Post reply on HN