I write C++ for a living and I like it, but it bothers me that we need a book that's essentially a list of "you can easily fuck this up by accident, watch out!"
for now, it seems that C is insufficiently expressive and everything else is too slow. but the complexity of C++ is troubling.
It's a multipurpose, statically compiled and standardized language. I don't think its complexity is a problem. Simplicity in a industrial level language like C++ can't really be expected.
I'd say C++ is a for a multitude of uses, it allows to do things precisely and well, but it has a cost, the one of learning how to use it.
1) There are many other alternatives than C++ that will cover a lot of use-cases. You don't always "need" to use C++, unless you have precise needs all the time, or don't want to have another language interact with your code.
2) You can still use C++ and avoid complex features, or just use C.
3) The language keeps evolving, and I think it's great that companies are working towards an ISO standard. Few languages have that. Maybe the language will be a little easier to use in the future.
C++ is complex in many ways which are unrelated to its core functionality. For example: most vexing parse, integer promotions, conflated language features (classes provide records, polymorphism, namespacing, encapsulation), header files, vector<bool>, the grammar is insanely complicated, et cetera. C++, like Common Lisp, is a standards effort which places more value on preserving the ability to run existing code than it does on removing language warts. Tools are now appearing like clang-format, clang-modernize, ReSharper, etc., but the equivalent tools have been available for other languages for quite some time now because those languages don't have the same complexity just at the syntactic level that C++ does. For example, Python has "2to3", and this was made with far fewer resources than "clang-modernize". Sure, C++ has richer semantics. But the syntax really is a maze, and if it weren't, we could have had our tools longer ago.
Well many of those issues are inherited from C, and Stroustrup has stated that compatibility with C was an absolute prerequisite otherwise C++ would have been stillborn. Given its position now, it's impossible to say that he was wrong, although I wonder if certain things could have been tidied up that would only have compilation-failed really bad code (e.g. it annoys me that you can pass a floating point value where an integer is expected).
While that's true, a lot of the complexity is self-inflicted. C++ tries to define syntaxes for its features in a C style which cripples a lot of features in unnecessary ways. For example, classes being kinda like a C struct instead of a separate syntax altogether.
Honestly, even Objective-C is better in this regard because the Objective-C parts are well separated from the C parts instead of feeling wedged-in.
I would argue that's "better". As a result, Objective-C feels like an alien language for a C programmer. Although to be fair I don't think a core C programmer would move to either C++ or Objective-C unless (s)he has to (iOS support or legacy code). I think it is the same reason why C++ developers are not moving to Go anytime soon.
I'd gladly move to a language that has the syntactic sugar of C++ (STL, lambdas, modules, and many other things) without the complexity (templates, inheritance, polymorphism).
Go and Rust seems to have weird syntax differences with C and I don't understand the utility of those. The go function syntax looks a little bit hairy.
C++ isn't evolving; it's just accumulating features. That's a crucial difference. The amount of harmful patterns you can accidentally use just keep on strictly increasing.
MY "observation" is that your "observation" cannot be trusted because you're being "unfair" in your "characterization" of C++'s new features as being the negative phrase "accumulating features" rather than "evolving" despite the idea that "evolving" implies getting "new features".
Maybe the language will be a little easier to use in the future.
this is always double with C++.
At one point, it most definitely is easier to use now already than pre-C++14 or 11. Lots of those additions really make me enjoy using it (even more:) and often lead to less code which does the same while still not being harder to understand (often even better to understand) and having the same performance.
However, because of the backwards compatibility there still is cruft around which does make it harder to use because you basically need to know how to use it or in most cases that you shouldn't use it at all. Ideally one just wouldn't need to spend time / 'brain resources' on that kind of stuff. Simple example: I can still use std::auto_ptr. I won't because there are much better alternatives. I can still use std::tr1::shared_ptr. I don't, and I know what it is when I see it. But for a newcomer or slow learners this is just utter nonsense: need to figure out wtf tr1 is, why it exists, what to do with it, and so on.
Couldn't these things just be deprecated? As in, never removed because of compatibility, but when compiling you would get warnings about using features no longer 'best practices', and maybe there could be a switch for 'modern c++' that would turn use of these features in errors?
Yes that would be ideal - in practice it is also not extremely hard as most of these things aren't baked in to the compiler/linker but can be solved with (a lot) of #ifdefs. The harder part is likely getting such thing into the standard: decide what will be deprecated and what not.
The price for zero-cost abstractions and expressiveness is a monstrous complexity. If you want clean, expressive and easy-to-write code, you have a ton of languages where you can do just that. If you want performance and expressiveness, you will have to do with C++'s complexity.
Speaking of backwards compatibility, I much prefer C++'s overzealous stance over the instability and inconstancy of Rust that prevents it from being used in any serious work. This is okay, it's a beta. I'll reserve judgment on Rust for now.
But Rust also introduces complexity, while improving substantially in many areas. Of course it will do things better than what a language initially designed decades ago will do. A large amount of important systems rely on C++ and so it cannot change overnight, if at all. Rust on the other hand is free to experiment. The cost, at least in this early period, is unreliability.
When, or if, Rust becomes as performant as C++, with a comparable number of libraries and platform support, then it will be a viable alternative (and I hope that day comes). For now, the only possibility for this use case is C++.
LLVM helps a lot here. We're generally in the same order of magnitude, sometimes faster, sometimes slower. It depends, as always with performance.
> comparible number of libraries
Yeah, this is a big one. If those C++ libraries also expose a C interface, we have zero-overhead FFI, but not all of them do. Crates.io currently has 1,893 packages, with a million and a half downloads served so far. It's a start, but always a weakness of a young language.
> platform support
LLVM helps here too, though there will always be some embedded platforms and such that ship their own C or C++ compiler.
I think Rust is going a pretty good job of adding a similar level of complexity. I see most of this due to the new abstractions they have added like lifetimes and borrowing. With the old abstractions we have kind of figured out the least confusing way to implement them.
I think initial impressions of Rust may make it seem a lot more complicated than it is. That's not saying it's simple, but it doesn't have the same kind of dark corners and 'surprising' interactions that has C++ (often due to backward compatibility requirements); most features in Rust are pretty orthogonal and minimal.
Having the compiler on your back about lifetimes/borrowing is definitely unfamiliar, but, fwiw, a programmer usually has to be keeping track of that in C/C++ anyway (if it's complex when the computer checks it, it's complex when a human checks it).
Yeah, instability is definitely a good reason for people to not use Rust, although that's quickly being resolved, both in theory, with the stable 1.0 release in just over 3 weeks, and in practice, with the recent 1.0-beta release.
Yes, exactly. In particular, this can be seen in the syntax. There are lots of angle brackets and colons these days. I hope at some point, around 5 years from now, a version can be made that is nearly the same thing underneath, but looks more like python.
There are many applications that either aren't typically IO bound, or where the IO (eg. gpu<->memory) is fast enough that you'll likely need C++ to maximise performance.
Writing software that pushes bleeding edge hardware is fun, which is why many people still want to learn C++.
Statistically I've no doubt you're right. However there are still a bunch of jobs where performance matters. If I left my job and industry, I'm fairly certain I could find another employer that found value in having a specific piece of code run as fast as possible.
Not sure if this way of comparing programming languages (i.e. do A in language X and do B in language Y => Y is not slower than X) makes enough sense to draw conclusions. If you can use clever algorithms, in the majority of cases you'd do so in any language and in the majority of cases C would lead to more performant code than Python. Then again, wheteher this matters in the scope of the actual application is something else.
I suspect his comment meant to imply that a level of skill exists for which a programmer could build an FFT in python, a plain DFT in C, but not a proper FFT in C. That programmer would benefit from using python.
Theoretically this is true, but in practice, those who need to write very efficient code competitively, rarely use naive algorithms. (Pure C/C++ also isn't enough nowadays though, the processor isn't competitive with the GPU in a lot of algorithms, so CUDA/OpenCL needs to be also used in most cases.)
I think the replies to this post are getting confused between the FFT/DFT, which is O(n log n), and the "naive Fourier transform", O(n2).
My experience with numerics in regular python is that they're generally 50-500x slower than the equivalent in C/C++, this just pushes back the point at which the asymptotics take over.
My point is that a good algorithm, a good strategy can give you a several orders of magnitude speedup, more than the speed differences among languages. If a higher level language makes it easier and faster to develop good algorithms, then you should use that. After that, if you have time or really need it, you can re-implement it in hand-coded assembly, or even in hardware. But you generally don't have the time and don't really need it.
Because the FFT in python is almost certainly implemented in C, and probably more cleverly done than a naive FFT that I/you/someone would whip up as part of a C program.
Is this a joke? Something written with the same algorithm in c will be faster than python. Why not use someone elses non naive FFT impl in c then as well?
I think the argument isn't that Python code out performs C code, it's that code written by mediocre Python programmers often outperforms code written by mediocre C programmers. C code is fast enough the mediocre programmers get used to letting the language bail them out. Python programmers know that their language is slow and that they have to work around it.
I've encountered this several times in my own career. A co-worker who writes in C will be implementing a process in parallel with my Python implementation. A week later, my O(N) Python code is outperforming my colleagues O(N^3) C code, since I chose a more complex algorithm which is trickier to get right. The C programmer then re-implements my method in C, which would completely trounce my own code, except I've spent that time leaning on BLAS and LAPACK, speeding up my operations again. The C programmer then starts using fast libraries instead of her own code, again beating my old source, only to find that I've now pushed a good chunk of the processing onto the GPU.
Eventually, I will run out of tricks. The final draft of the C code will trounce the final draft of my Python code. However, during most of the creation process, my Python usually out performs their C. Also, a truly talented C programmer would write my colleague's final draft as her first draft, negating every advantage that I had in the process. However, that's not a situation that I'm likely to run into, because places hiring truly talented programmers aren't likely to be hiring me.
Makes literally no sense. The c developer would simply use the same c/fortran library the python implementation is based on. You are creating a false dichotomy for the sake of it.
The c developer should use the same c/fortran library that the python implementation is based on. A good C developer would use that library. In my experience, mediocre C developers will not use that library and will implement their own, naive version.
This comes out of the fact that C++ is being developed more as an engineering tool than as a programming toy. When you're into real engineering, you don't have free lunch.
I disagree. I see most of the complexity of C++ as being due to design mistakes which have to be maintained for backwards compatibility. I would personally like to see a breaking change where a lot of the inconsistencies and design mistakes that have been identified are rectified.
You can see this with Rust which tries to satisfy the same niche. It's possible to avoid the gotchas in C++ while preserving the advantages, you just pay a different price by working harder to satisfy the compiler.
A lot of people working with C/C++ I know are looking forward to Rust, but the problem is that currently it's nowhere near as mature and widespread as former languages. I hope that will change in the near future as it looks like promising system language.
Honestly, I haven't tried D, but if it hadn't got traction in 14 years, I'd say it was a miss. It's not enough to be a good language -- documentation, tools, libraries, community, adoption in open source projects is, arguably, even more important.
This is the attitude that keeps us mired in subpar ideas like C, C++, Java, HTML, CSS, JS.
"I'm a tough guy and tough guys use tools that make our lives hell! We're serious! We're engineers! Your language is just a toy because our managers want to keep us fungible!"
What does an average "real engineer" C++ programmer have at their disposal? C++ has an ersatz type system (not algebraic and not connected to type theory) and an ersatz macro system (templates and preprocessing) and it offloads type signing onto the programmer (no help from an inferencer). It also lacks a garbage-collector because its followers are still afraid of non-existing "performance penalties". C++ has an ambiguous grammar that is context-dependent and requires infinite lookahead. Its creator is not any revolutionary thinker like Alan Kay, just some guy that wrote a language and become famous for writing that language. He also said that we hear a lot of complaints about C++ just because a lot of people use it, not because it's crap.
But bullies like restalis rejoice in the fact that know-nothing managers keep choosing C++ because it's the industry bandwagon and you can count on universities to supply the market with a fresh load of programmers trained in mediocre tools time and again.
"What does an average «real engineer» C++ programmer have at their disposal?"
Ways to do the job. C++ is not perfect, I contest some of its design decisions (like having private class members by default, and having to explicitly (i.e. verbose) declare "public" at least some of them to make that given class usable), but I don't have to fight the language so much to get things done. For me the best job C++ does so far is by staying a tool. I don't want _BY_DEFAULT_ "something more", "something clever", or "something whatever" that adds more accidental complexity [1] which comes around when least expected and gets in my way! This being said, I admit that C++ suffers from feature creep like many other things do, but (as a consolation) it got here like this only after serious critique for each of the added feature and each feature had to pass serious filtering in order to "creep in".
"managers keep choosing C++"
Actually, I am the one choosing C++ for what I do, be it corporate related (and managed by managers) work or personal projects. I choose it for both low level and almost scripting-like tasks, although I used (and consider myself proficient in) other toy programming languages too.
for now, it seems that C is insufficiently expressive and everything else is too slow. but the complexity of C++ is troubling.