Live data from Hacker News

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

250bpm.com

121–130 of 147 posts

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

#121
post #120
post #115

Earlier quoted context omitted.

Mostly inherited from C, actually.

Well, "defect by design" is still a defect and I have to work around it on almost daily basis. Besides, being able to do (bool+int) could not come from C since C didn't have bool at the time. EDIT: actually, there are two defects here. One are the implicit numeric conversions. The other one, which causes me most grievance in this context, is that size() on containers returns an unsigned type.

I'm curious about that last bit. I occasionally hear this argument that size_t being unsigned is a bad thing. Presumably the standard library designers would claim that a size cannot be negative, so this is appropriate. Why, in your view, should that be a signed quantity?

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

#122
post #119

Earlier quoted context omitted.

> Actually avoiding C++ pitfalls is not that difficult as most of them come from C If you really believe that, then you're probably writing dangerous code and not even realizing it. Most C++ pitfalls come from subtle interactions between features that don't even exist in C, like exceptions, move semantics, templates, threading, constructors/destructors, references, operator overloading, etc. Those are the things peop…

I don't always write dangerous code, but when I do I fully realize it =). And it has nothing to do with any of the features that you listed. In fact "threading" in C++ is safer because of the availability of high-quality libraries providing task-based parallelism such as TBB, move semantics is used all the time in C albeit manually with pointer manipulation. It is true that not all of the features play well together,…

> In fact "threading" in C++ is safer because of the availability of high-quality libraries providing task-based parallelism such as TBB, move semantics is used all the time in C albeit manually with pointer manipulation. It is true that not all of the features play well together, but it's nothing compared to the C pitfalls that I mentioned.

Well, if I use libraries to avoid C's pitfalls, that language will be safe, too.

> If you want to avoid dangerous interactions, don't overengineer your code, stick to the features you understand. This is true not only for C++, but for any language.

That's almost useless advice. You might as well say the key to using C++ is to use Python or C instead.

"Stick to the features you understand," doesn't even really work when coding by yourself. C++ is so incredibly complicated there's a very good chance most people wouldn't even really understand the limited subset they've stuck to. C++ devs with years of experience routinely mess up stuff like exactly when copy and move constructors are called.

For example, how many copy constructors get called in this code:

    const std::string myString{"omg"};
    std::cout 
Most people will have to think about it for a little bit, and a lot of them will answer wrong.

And that advice completely goes out the window when working with code written by other people. And it also means not using any C++ libraries because a lot of them use the full features of C++ and expect (or require) the code calling them use those features, too.

The key to using C++ is to be aware there are many pitfalls, know when you're working with features that are particularly dangerous, have some resources that can help identify and avoid them (like the Effective C++ books), and whenever possible have other people review your code.

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

#123

Earlier quoted context omitted.

How does a proper C++ constructor report errors?

Several solutions. First I can think of: don't create situations where error can happen. Compile with exceptions turned off. Out of memory? Terminate the process/thread. Another: create your objects using some factory, make constructor empty and initialize class by said factory once instance is already created (perhaps recursively instantiating its members). This way all error generating code will be moved outside of…

Compiling with exceptions turned off is highly unusual. If you do that, you're not really writing C++ anymore, as it's a fundamental part of the language. Exceptions are the mechanism provided for indicating that it was impossible to construct an object, and to trigger appropriate cleanup actions.

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

#124
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…

For anyone who is curious about the intended use of exceptions in C++ I recommend Jon Kalb's two-part tutorial on exceptions from CppCon 2014. First video is here: https://www.youtube.com/watch?v=W7fIy_54y-w

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

#125
post #119

Earlier quoted context omitted.

I don't always write dangerous code, but when I do I fully realize it =). And it has nothing to do with any of the features that you listed. In fact "threading" in C++ is safer because of the availability of high-quality libraries providing task-based parallelism such as TBB, move semantics is used all the time in C albeit manually with pointer manipulation. It is true that not all of the features play well together,…

> In fact "threading" in C++ is safer because of the availability of high-quality libraries providing task-based parallelism such as TBB, move semantics is used all the time in C albeit manually with pointer manipulation. It is true that not all of the features play well together, but it's nothing compared to the C pitfalls that I mentioned. Well, if I use libraries to avoid C's pitfalls, that language will be safe,…

> Well, if I use libraries to avoid C's pitfalls, that language will be safe, too.

I'm not talking about possibilities, but about libraries that are actually available and widely used.

> You might as well say the key to using C++ is to use Python or C instead.

And that might not be a bad idea. If you don't need the power of C++ or don't want to invest time in learning it, then you are better off using a simpler language such as Python, but probably not C for the reasons I pointed out earlier.

C++ is a complicated language, so I agree with your advice of using good learning resources and code review. I don't agree that the issues you mentioned are of the same level as the ones I was talking about. Missing a copy constructor is just not as big of a problem as, say, getting a segfault caused by misuse of varargs.

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

#126
post #106

Earlier quoted context omitted.

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

I may have misunderstood your terms, so I apologize if my response doesn't cover what you're talking about.

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

I believe you're talking about C++ export. Everybody will say that export was too complicated to implement; although (1) the full sentence should be "too complicated to implement, using current linkers," and (2) both CFront and EDG implemented did implement export using current linkers CFront implemented it in the early '90s), so the argument that it can't be implemented is simply wrong. It is accurate to say "using current linkers, refusing to use nonportable linker features, and following the Borland template instantiation model ( https://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.ht... ), it is hard to implement export; only EDG ever paid the price to do so."

But the C macros to #declare dllimport/dllexport (which is what I thought your original complaint was) are meant to solve a Windows linking issue that plagues C as much as it plagues C++. And, to be honest, it's a link time optimization that non-Microsoft linkers don't appear to have trouble with.

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

#127
post #120
post #115

Earlier quoted context omitted.

Mostly inherited from C, actually.

Well, "defect by design" is still a defect and I have to work around it on almost daily basis. Besides, being able to do (bool+int) could not come from C since C didn't have bool at the time. EDIT: actually, there are two defects here. One are the implicit numeric conversions. The other one, which causes me most grievance in this context, is that size() on containers returns an unsigned type.

> Besides, being able to do (bool+int) could not come from C since C didn't have bool at the time.

Except that

    typedef int bool; /* or BOOL */
    #define FALSE 0
    #define TRUE (!(FALSE))
used to be quite common back then. So C++ only adopted an existing idiom in the C community.

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

#128
post #125

Earlier quoted context omitted.

> In fact "threading" in C++ is safer because of the availability of high-quality libraries providing task-based parallelism such as TBB, move semantics is used all the time in C albeit manually with pointer manipulation. It is true that not all of the features play well together, but it's nothing compared to the C pitfalls that I mentioned. Well, if I use libraries to avoid C's pitfalls, that language will be safe,…

> Well, if I use libraries to avoid C's pitfalls, that language will be safe, too. I'm not talking about possibilities, but about libraries that are actually available and widely used. > You might as well say the key to using C++ is to use Python or C instead. And that might not be a bad idea. If you don't need the power of C++ or don't want to invest time in learning it, then you are better off using a simpler langu…

> I'm not talking about possibilities, but about libraries that are actually available and widely used.

Then your original statement makes no sense. The C pitfalls you listed are easily avoided using C++ builtins like std::shared_ptr, templates, the STL, and the rest of the C++ standard library.

> I don't agree that the issues you mentioned are of the same level as the ones I was talking about. Missing a copy constructor is just not as big of a problem as, say, getting a segfault caused by misuse of varargs.

And I'd have to strongly disagree. Some of the pitfalls in C++ are worse than crashing because they can (potentially) silently corrupt data. Pass around pointers or references to objects in an inheritance hierarchy without paying attention, and it's not hard to get memory "slicing" and data corruption. Not understanding the intricacies of std::atomic can cause insanely hard to reproduce deadlocks. And I could go on all day.

At the end of the day, I just think it's flat out wrong to say that most of the pitfalls in C++ come from C and are easily avoided. The C pitfalls are easy enough to avoid, but the new C++ specific ones are just as bad, and usually more difficult to understand and spot in real code.

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

#129
post #125

Earlier quoted context omitted.

> Well, if I use libraries to avoid C's pitfalls, that language will be safe, too. I'm not talking about possibilities, but about libraries that are actually available and widely used. > You might as well say the key to using C++ is to use Python or C instead. And that might not be a bad idea. If you don't need the power of C++ or don't want to invest time in learning it, then you are better off using a simpler langu…

> I'm not talking about possibilities, but about libraries that are actually available and widely used. Then your original statement makes no sense. The C pitfalls you listed are easily avoided using C++ builtins like std::shared_ptr, templates, the STL, and the rest of the C++ standard library. > I don't agree that the issues you mentioned are of the same level as the ones I was talking about. Missing a copy constru…

> The C pitfalls you listed are easily avoided using C++ builtins like std::shared_ptr, templates, the STL, and the rest of the C++ standard library.

That was exactly my point.

> And I'd have to strongly disagree.

OK, let's agree to disagree.

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

#130
post #84

Earlier quoted context omitted.

C++ not only fails to hide the above-mentioned C pitfalls but adds entire classes of pitfalls of its own. Just a few examples: * undecidable grammar: http://yosefk.com/c++fqa/defective.html#defect-2 * const inside containers: http://yosefk.com/c++fqa/const.html#fqa-18.1 * template error messages http://yosefk.com/c++fqa/templates.html#fqa-35.17 C is often nicer than C++ because it's simpler: it only has the C pitfall…

These are trivial issues compared to major safety and usability flaws inherited from C that I mentioned. BTW the C grammar is not context-free either. The compilation speed is mostly due to header system which is again a C heritage, not because the C++ grammar is undecidable. And template error messages are much better now in modern compilers such as Clang. As for the const, its semantics is the same as in C.

The super-slow compilation speed is mostly because C++ encourages massive all-inline template libraries like the standard C++ library and boost, which need to be parsed and have the used templates instantiated for every compilation unit.

Here's idiomatic hello world, with vs.

> g++ -E hello.cc | wc -l

17906

> gcc -E hello.c | wc -l

842

Post reply on HN