Why C++ is back
devbug.tumblr.com
devbug.tumblr.com
The language is too big [it's always odd to see some people say things like "the language is still too big", as if some recent effort has succeeded in making the language somewhat smaller, but not small enough... every recent effort has actually made the language bigger]
There are too many ways to write bad code and too few ways to navigate bad code. It's hard enough to pick up a big C# program and figure out what it does ... C++ is not easier.
I'm not sure why there's all this excitement over bit twiddling... every language lets you twiddle bits. I can only assume the cool feature here is mislabeled, and the authors are really excited about memory twiddling. Fair enough. It's fun to write code that touches data structures at a byte level. But it's not fun to read/fix someone's buggy byte manipulation code. If you're not writing a device driver, or your own compression library, then you should not do this.
Now, I am a big fan of people learning low-level system details, provided they do it with some small C program, or by doing a project for their OS or compilers class, or by maybe working on some open source project.
But anyone who chooses C++ when he doesn't need it reminds me of the kid who, rather than painting on paper, decides to paint on the carpet. You could do it. It's also probably a lot of fun. There's even the remote possibility that you'll improve the carpet. But you probably won't. You'll probably just make a mess. And it won't be fun to clean it up.
Or a cutting edge game, or a high frequency trading system, or a high performance server, or an operating system, or implementing a language, or a database, or a numerical library, or a crypto library, or a VM...
Again, you need to wrap your mind around:
(1) Some things will be written in C++
(2) C++ is not a synonym for "low-level." Many of your examples are really referring to C and assembly. Why would you prefer a C++ implementation of a crypto library to a C one?
(3) The vast majority of computer code written today is not for any of these systems. Lots of code uses these systems, but most people are happy with language bindings for a crypto API. Or to a numerical processing library. Or running on a VM running on an OS.
Does anyone have empirical data that the C++ fraction of software written today is increasing? If so, then you have a case. I'm going to guess that that fraction has been falling for quite some time, and will continue to fall.
I agree that there is a ton of code being written where byte-level manipulation is not needed and is not appropriate. But there is still a ton of code where it is needed or appropriate, and you misrepresent that when you say you shouldn't be doing it unless you're writing a device driver or compression library.
Here's an example from the EVP_Digest* man page from OpenSSL, with some comments added:
EVP_MD_CTX *mdctx;
// forget this part and get undefined behavior (but maybe it seems to work, sometimes)
mdctx = EVP_MD_CTX_create();
// forget this part? more and different runtime errors
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, mess1, strlen(mess1));
EVP_DigestUpdate(mdctx, mess2, strlen(mess2));
// md_value allocated with malloc()? don't forget to free()
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
// forget this part, or remember it but miss an "if(err) return -1" statement somewhere? memory leak
EVP_MD_CTX_destroy(mdctx);
Comparable C++ implementation:
// RAII, compile error if you don't provide constructor argument instead of runtime error if you don't call init function
EVP_Digest_CTX ctx(md);
ctx.update(msg1, msg1_size);
ctx.update(msg2, msg2_size);
// return simple object: typed dynamic byte array + size with its own destructor, both digest and ctx destructors get called when function returns from anywhere
EVP_Digest digest = ctx.final_result();
And it's 4 lines of code instead of 7.
Can you explain why I would want the C version?
Additionally Microsoft is now replacing parts of the Windows C codebase to C++, as mentioned at the latest Build 2012 conference.
With respect to bit-twiddling, the advantages of C/C++ are not intrinsic; many other languages have broken implementations for this purpose. For example, a glaring deficiency in Java is the lack of large unsigned integers which are useful for many types of algorithms. You can always implement these algorithms with signed integers but they may be much slower as a consequence.
For most people though, memory control and optimization is the primary reason to use C/C++. While I can see why it is difficult code for people uncomfortable with it, I think you overestimate the complexity for people that have done it for years. Like LISP, you have to become used to it. It is similar to the reason why, despite some arguments, there are many huge C/C++ code bases that rarely leak memory despite very active development. Proper idioms and use are a discipline like anything else.
C++ is never coming back for front-end applications. It is unnecessary and inefficient for that purpose. However, on the server side (where I do development), C/C++ is expanding very rapidly. Five years ago almost all of the server engines I worked on were written in Java. These days, all new development is in C++. The reasoning is pragmatic: C++ offers much better performance and latency characteristics for server engines, primarily due to its excellent memory behavior and efficiency. The latency and throughput differences are often integer factor relative to other languages for server workloads, so it is not a small difference and people are very sensitive to operational costs and footprint these days.
I pretty much hated C++ for years but with C++11 it is not great but it is adequate. Too much junk glued onto the language too many times. But until something remotely as capable becomes widely used, C++ will be with us for a long time, particularly as power efficiency becomes more important.
I assume you are using IE, Firefox, or a WebKit browser to read this; that means you are using a majority-C++ front-end app right now!
In web browsers, text editors, video editing, IDEs, games, etc, there's hardly anything that can compete with C-derivative languages. Exceptions do exist (Eclipse, Minecraft) but are universally slow.
Consider that operating systems are tremendously sophisticated user-facing applications in their own right, and that dwarf the high level "web browsers" they support in complexity. ;)
I would say that the basic reason is we still need systems that both customize their low-level (literal and metaphorical) bits and use large scale, powerful abstractions. Indeed, it worth remember that very high-level abstract systems (such as databases) often wind-up simultaneously crunching lots of data in unique ways and thus needs *particular" sorts of low-level operations along with a variety of high-level constructs.
C++ has succeeded as a tool allowing you to do nearly any kind of abstraction up from the low-level operations implicit in c. And given that this is a broad mandate, the language comes out "too big" seeming, "too wordy" seeming and so forth. Not a nice language but efforts targeted to a similar area have wound-up making similar compromises and thus having equivalent problems (see the D Language - not that its failure but that it seems to have failed to be lots better than c++). C++ can be "the best language" (for its purpose) without being "a good language" (without being a pleasant or sane-seeming language).
As jandrewrogers said, (at least the best) c++ projects use less than the entire language and use it according to their needs. Merely having good parts is not enough to make a language good but until we have a good alternative to c++ or until we have garbage collectors and virtual machines that are guaranteed to work best for any significant system whatsoever (good luck with that), c++ will have a place.
Since then a lot of higher level languages and frameworks have whittled down C++'s domain to what it is actually good for, and that's a good thing.
But I write high-performance realtime audio software and C++ is really the only language that makes that possible while maintaining a sane level of abstraction.
Not many developers get that much in the Valley...
There are very different staffing dynamics when it comes to C++ projects versus projects written in Java, Python, Ruby, PHP, JavaScript and languages like those.
In my experience, employee turnover is far greater when dealing with higher-level programming languages, and especially when it comes to web development. The overall skill level of these developers is generally far lower than what we see from even an entry-level C++ programmer, and it's much easier to replace them.
Those who have overcome C++'s more significant barrier to entry can often command greater salaries and more stable employment situations. They are often working on absolutely massive projects where it can take some time to get up to speed. We aren't talking about simple CRUD web apps, for instance, where an average developer can get a pretty good comprehension of the entire system within a few days.
So we see C++ being very heavily used, but with development and maintenance being performed by stable teams that will often work together for many years, if not decades in some cases. The lack of near-constant turnover really cuts down on the need to advertise for open job positions.
Furthermore, we often see many C++ hires coming via referrals from other C++ programmers or other contacts, rather than through advertisements or job boards. It's actually a relatively tight-knit community in many areas and industries.
C++ may not be as immediately visible as Java, Ruby, JavaScript and other languages, but it's still extremely, extremely important, and still very widely used.
Sir, you nailed it.
I've noticed the same thing in my company. There are a handful development teams currently present and almost all of them do various Java based consulting gigs for external clients. Most of that is CRUD based web form twiddling. And as it happens, the turnover rate on those teams is often through the roof.
However, there is also one C++ team which does in-house development on a very critical piece of software and I've noticed a couple of things about those guys: they not only appear to be far more technically competent than their Java counterparts, but the turnover is nearly nonexistent. While other teams have seen massive turnover to the point of being unrecognizable after a period of time, the C++ team hasn't changed at all... and the funniest thing is, a lot of people are internally applying to work on that team but these guys are extremely selective about who they let in.
There's definitely something to be said about C++ development and the effect it has on stability/turnover in dev teams.
I know C++ very well, but I also know Ruby well.
Some startups *ARE* using them, just not web/app startups. C is still heavily used in algorithmic, infrastructure, and networking startups - But they're a different crowd. More neckbeard and device drivers than TechCrucnh and Rails.
But I do agree that it's use cases have been marginalized more.For writing operating systems, browsers, and other serious apps c/c++ is pretty much universal.
Not being a hipster here, but I've experimented with Go lately, and while it is not ready to become a main stream language - it is certainly a very powerful one and a good replacement for a lot of the stuff I've been doing with C++ and could not have been done with Python & friends. I'm glad it's in my toolbox now.
My default language used to be C or C++, but nowadays given the chance I code everything in Python [1], from throwaway scripts to medium size fetch/process programs. The performance is usually acceptable, and normally IO bound.
What also enables this is advances in modern architecture. 64bit processors allow for large address spaces and large stack frame sizes, which obviate the need to allocate every single bit on the heap. You can often see sizable C++ programs measuring around 100KLOC or larger which use new/delete in a handful of places. Automatic storage is, well, automatically managed. For when free store semantics is needed, smart-pointers abstract the complexity of several common cases where automatic-management is not adequate.
Using value semantics, streams, lambdas, regular expressions, and a good library for command line flags processing (e.g., boost) C++ can even be a perfectly apt choice of language for scripting. The development effort need not be much longer than python but with no optimization the result can be easily 10 times as fast.
Bjarne vouches for abstractions. Everyone does. What does Bjarne + standards commitee do? Make old stuff useless, yet make sure the user has to deal with it. Make new stuff so the language becomes more complex. Why do we want abstractions again? Because we want to get rid of useless stuff and make things simple instead of make them complex! What does C++11 do? It goes to the wrong direction. Very, very nice.
When will we have something simple instead?
C++ is hard to appreciate without a good amount of programming experience.
A general pattern I am seeing is that programmers learn C++ as their first language, move to Java, Python, etc.. gain some experience and then they come back to C++ and say you know what, C++ is not that bad after all. But they don't come to this conclusion because C++ changed, but because they learnt to appreciate its usefulness.
After all, use the right tool for the job.
It is Reflection/introspection capability built into the language.
Without it -- it is impossible to do DB structures to C++ structure mappings, or UI fields to C++ structures mapping.
There are of course work arounds (QT's macros, pre-compilers, etc).
Every time I approached this topic with some in C++ community, the answer always was ' C++ philosophy is -- if you do not use a feature of a language you will not pay a performance penality for it'.
Reflection, obvsiosly adds performance penalty. When I suggest that it should be a compiler switch (like RTTI) -- the reply I get -- is that reflection cannot be turned on/off on per compilation unit., and instead must be on per project level. But C++ standard does not define 'project level' compilation option -- therefore, not acceptable.
That's pretty much where this discussion gets stuck
There's a library called Reflex: http://root.cern.ch/drupal/content/reflex
SOCI uses generic template accessors to read/write full objects: http://soci.sourceforge.net/doc/exchange.html#object_relatio...
After changing teams about a year ago, I came back to C++. IMHO, C++ is the worst. By far. Without question. It's so bad I don't know what to rank as second-worst. Every new feature or quirk is tinged with horror. The latest example for me was: http://isocpp.org/blog/2012/11/universal-references-in-c11-s.... So was that HN piece about C++ pitfalls.
No, for me, it is the diametric opposite. The more I learn about anything other than C++, the more C++ seems like a big, creaking pile of leaky abstractions. It's like if you took the worst aspects of C and Java. And I struggle — earnestly — to imagine how people could actually be OK with it, let alone enjoy it.
But I have to use it at work. It's an industry-standard language. Some people like it. That's life.
Does anyone know if this situation has changed? I can see his new book on Amazon is due out in March.
However, one big fact that is being left alone here is that there is no inherent speed bonus in using C, C++ or ASM over C# for most cases.
C++ apps can be faster than C# by a good margin, but you need to be able to program better in C++ then the C# compiler does in translating your good C# code. Simply writing in C++ != faster code. You have to beat the machine.
Two years ago I have heard about many benchmarks, people saying that higher level languages can be nearly as fast. (Or even faster!) In fact I even believed this because it was said so often and Ruby for instance went fast.
However reality proofed me wrong. When the CPU is going to 100%, C/C++ are always faster. (In case of Ruby it can be orders of magnitude...) However when doing mostly I/O-intense web apps, it pays to have a language that makes performant design easy.
C# and Java can produce very efficient programs, and for a lot of CPU-bound problems the obvious solution in either of those will be faster, particularly stuff that needs to perform lots of little allocations or where the obvious C++ program does too much accidental copying.
However with C++ it's easy to work around that by using pointers or (const) references. Or even one step further one can use a memory pooler or GC.
- Netty vs Nginx - Tomcat vs Apache - Jake2 vs Quake2 - H2 vs PostgreSQL (there is no clear performance winner here)
However, to achieve good performance in high-level languages, I'm afraid you still need a pretty deep low-level knowledge, so learning C can be very beneficial.
If they choose Java, they often get a slow, bloated, extremely over- "engineered" system. Although simplicity is often given as one of the reasons for using Java over C++, the complexity of these Java-based systems often far exceeds what we see from even large C++ systems.
If they choose Ruby, they are almost guaranteed scalability problems if the software is to be used by a large number of people. The effort and cost needed to scale a poorly-performing Ruby on Rails web application, for example, can exceed that of using a language like C++ in the first place.
When it comes to other languages, it may be difficult to find talented developers. This can pose big problems when it comes to maintaining software systems written in a more obscure language.
C++ has time and time again shown itself to be a safe bet. There is a large, experienced and global developer community. There are ample resources and tools available. It is extremely well proven, even for absolutely massive systems. Systems developed using it usually perform quite well without much effort.
It offers a better set of trade-offs than other languages. While it may take longer to develop a system using C++, there is often at least equal, if not much greater, time saving in other respects. Avoiding scalability and portability problems alone can offer massive savings.
"For all program aspects investigated, the performance variability due to different programmers (as described by the bad/good ratios) is on average about as large or even larger than the variability due to different languages."
But I still wouldn't discourage people from learning C and C++. They're not magical fast code juice, but being able to work closer to the machine when it does make sense is obviously better than not being able to. All of the good programmers I know personally can work in at least one of the two.
Besides, people deciding to learn C and C++ just might become good enough to beat the machine after all.
Which is too bad. There's almost nothing about the language that makes it a good language. Even the so-called beauty of C++11[1] isn't usable by most practical C++ developers at this point because they are stuck with compilers that still struggle with rational C++98 and C++03 compliance (I'm looking at you, HP-UX aCC). Or maybe they've got something that's older and mostly compliant with C++98/C++03 because you have a hardware partner who only provides something that is compiled with VS2005 and won't sell you the source because you're not a large enough partner for them to give a damn. And gods help you if you have an error related to templates unless you're lucky enough to be using clang or can use an error filter to make the thirty thousand lines of errors readable, even if they aren't directly applicable to the missing semi-colon at the end of your class declaration.
It will be 2015 before most C++ developers can even think of using anything from C++11 in a production environment, if their (almost certainly mandatory) coding standard allows for it. C++ requires coding standards because you really can blow off your leg.[2]
Not only that, features that would be vitally useful in many applications like real introspection continue to be missing for no good reason at all. Multiple inheritance is an absolute blight on the language, and the fact that the `explicit` keyword even exists is problematic (or that constructors are, by default, not virtual).
All of that said, there's a lot of C++ code out there and it's a good enough language for a lot of functionality, even though it's neither a humane language nor a particularly secure language. There's a lot of libraries out there, and they work reasonably well. For a lot of solutions, the problem isn't finding if there's a library to help you do something, but picking a library from a couple dozen implementations and making sure that some other library you depend on doesn't implement the same thing differently…and then making sure that what you pick actually works with the compilers you've chosen or had forced on you.
If you're truly lucky, you work in an environment that lets you do the bits that you must do in C++ without too much issue, and then you can use Python, Ruby, JavaScript, Lua, or something else to drive the higher-performance code with languages that better express business algorithms.
I'd still rather use Ruby for my whole program (when I had time for OSS projects, I even explicitly went with pure Ruby solutions because of compiler issues), but there are places where C++ isn't just the right tool, it's damned near the only viable tool. A full stack developer needs to know it. I'd argue that most devs should learn C++ just so they know how badly a language can be designed and still be useful for developing modern software.[3]
[1] I'm sorry; the C++11 lambda syntax is unbearably ugly.
[2] http://www.stroustrup.com/bs_faq.html#really-say-that He tries to backpedal from this truth. Other languages that are more expressive and IMO more powerful because of the greater expressiveness do not offer the same capability to break things as badly.
[3] Yes, I know. Most of the issues I have with C++ are probably fixed in C++11. It's impressive. It's still a crappy language with even worse compiler support. Far too much of the language is focussed on making me adapt to the compiler, when with modern type inference and a little convention-over-configuration or even hinting, you could probably cut the size of any given C++ program in half (in terms of number of characters) while not losing a thing in terms of optimization.
Back in the old days we used to say "I have a compiler/interpreter for language X", not state that "Language X is compiled/interpreted".
Slowly I am starting to think it should be compulsory to understand compiler design, before writing any blog entry about programming languages.
Powerful language full of features yet programmers are scared to use most of them.