* 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?)