* 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 pitfalls not the combination of C & C++ pitfalls that plague C++.
Here's idiomatic hello world, with <iostream> vs. <stdio.h>
> g++ -E hello.cc | wc -l
17906
> gcc -E hello.c | wc -l
842
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 people are talking about when they mention the pitfalls of C++.
The things you mention are the pitfalls of C, which technically still exist in C++, but they're not as interesting there because the C++ pitfalls are so subtle and dangerous.
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.
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.
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 << myString << (myString + myString);
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.
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.
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.
That was exactly my point.
> And I'd have to strongly disagree.
OK, let's agree to disagree.
""" A generic library should be able to calculate the distance: for any point class or struct, not on just this mypoint type in more than two dimensions for other coordinate systems, e.g. over the earth or on a sphere between a point and a line or between other geometry combinations in higher precision than double avoiding the square root: often we don't want to do that because it is a relatively expensive function, and for comparing distances it is not necessary """
I suspect a little bit of complexity is necessary. (And can you even build something like this in a more fashionable language?)
The weird thing about C++—and the reason it didn't just absorb/replace C—is that it gives you the ability to encode strictly more nonsensical things than C does. In that sense, C looks more like the descendant of C++ than the other way around!
Yet the most famous current C compilers are all written in C++.
If it wasn't the rise of open source and its community attachment to C, mainly in GNU and BSD circles, C would have been long replaced except for the embedded space.
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 ~3x difference, but not quite the order of magnitude I'd expect from huge vs small.
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.
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.
How would you prefer to compare language sizes? Gut feel? Surely that's even worse.
I'll certainly admit that - like LOC measurements - it's a metric one can't take too seriously on it's own. On the other hand, it's a useful starting point for discussing said variables.
For example, when I was eyeballing the Javascript standard (I've already read the C++ standard a decent bit), I saw it (like C++'s) defines a grammar, and includes some core library bits (e.g. the Object type.) On the other hand, I didn't see the full browser DOM API you'd use when writing most Javascript - but then again, you don't see any modern graphics or UI widget APIs in the C++ standard either.
This was enough to convince me that they were comparable enough for an orders-of-magnitude comparison, at least. My gut reaction was that C++'s standard might be more detailed - but that'd be biased in my favor, further undermining the argument that Javascript is significantly smaller than C++.
> I can write a 10,000-page standard for Scheme if you hire me to.
But can you find a 10,000 page standard, for any language? Eventually everyone hits a limit to what they consider worthwhile to write, short of perverse incentives.
> How would you prefer to compare language sizes? Gut
> feel? Surely that's even worse.
Why is it necessary to compare "language sizes" at all? Nobody has ever demonstrated that the "size" of a language (by any definition) has any measurable effect on the quality of the software written in that language. It's as pointless as the classic vim vs. emacs argument.It seems relevant in the context of how difficult it is to master a given language, which spawned this thread of debate. Do you disagree that language size is any sort of barrier?
Again, only one metric, to be taken with a measure of salt. But would you prefer we compare languages based on gut feel? Or is comparing languages unnecessary as well?
> It's as pointless as the classic vim vs. emacs argument.
Understanding the merits of vim vs. emacs informs you which you might prefer. The answer to that argument, over which is "ultimately better" is certainly pointless. You can simply choose whichever works best for you, especially as you can change your mind mostly at will.
But people don't simply have the choice of "choose whichever works best for you" when it comes to programming languages on a team project. Nor are languages as fungible as editors when it comes to changing your mind - switching languages mid-project is a massive time sink, and frequently fatal to the project.
EDIT: Said Wikipedia page was sufficiently detailed for me to implement a Brainfuck -> MSIL compiler without additional external references, which I was able to verify worked with a Mandelbrot renderer.
> 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.
Including the standard library.
I don't know about JavaScript, but at least Python, Java and C# are actually quite more when including the standard library.
I've done both and hunting things down in chrome's dev tools is orders of magnitude easier than figuring out what is going on in your c++.
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.
Just switching compilers makes the C code more robust.
And they certainly beat C's "equivalent", macros.
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.