This page is about C++98. C++11 and 14, while making some important things easier, have their own set of problems.
Which is why Yossi Kreinin called for help about updating the FQA for C++1x and beyond. As he no longer works with C++, both his expertise and the time he can waste on this language are dwindling. http://yosefk.com/blog/c11-fqa-anyone.html
And you can see the same shrewdness, the same "altruism", the same attention to detail, the same tunnel vision – "this shit I'm working on is so important, it deserves all of my mental energy AND the mental energy of my users at the expense of caring about anything else" – throughout the C++ culture. From the boost libraries to "Modern C++ Design" (the author has since repented and moved to D – or did he repent?..) to the justifications for duplicate and triplicate and still incomplete language features to your local C++ expert carrying his crazy libraries and syntactic wrappers and tangling your entire code base in his net.
So true.
In the beginning of my career, I too was drinking the C++ koolaid. I really believed that manual memory management, large and convoluted class hierarchies, obscure template programming, cryptic exception handling, and pointer tinkering was necessary in a language and, of course, to get good performance you had to use C++. What a complete lie.
I still meet programmers who believe that, because it is important. And then you look at what kind of software they are writing, some desktop app or some web service. Huh.
If you look where the C++ community ended up by C++ programming experience over the years is that you should probably avoid all of that if you want bug free code.
> I really believed that manual memory management, large and convoluted class hierarchies, obscure template programming, cryptic exception handling, and pointer tinkering was necessary in a language and, of course, to get good performance you had to use C++. What a complete lie.
It was a complete lie. Fortunately, none of that stuff precludes you from using C++.
True, and when I need to use C++ today I use a small subset of it with some new features from C++11. Namespaces, functions, structs, lambdas and smart pointers is usually all I need.
The standard library has become so much better then the old days. Now I can even create threads without extra libraries. Unfortunately std types are no longer COW with C++11.
Now if I only can get rid of that awful header file I almost have something that works without too much headache and profanity.
> Unfortunately std types are no longer COW with C++11.
GNU std::string being CoW (still is atm btw) has always been deceitful. The API was simply never designed for that implementation, which resulted in seemingly cheap read-only operations (char x = str[42];) becoming quite expensive.
I'm glad you mentioned actually, since API authors embracing reference semantics through fear of overhead is a great rabbit hole of systemic complexity for C++ developers who are then forced to swim against the tide in the language. Sadly I don't think Rust goes far enough in bringing love to value semantics.
Ah, I did not know that. I mostly use CoW when I do Qt stuff to get a clean API (but Qt gives you whole range of other annoyances). Qt data types works well together with std lambdas without the need of smart pointers.
In what other language has so many Stack Overflow threads and blog post been dedicated just how to pass a simple parameter to a function. And with C++11 we have one more way of doing it. It is really mind-boggling.
I never have this problem in other languages and I can do equal the heavy lifting.
And for the C++ programmer it gives a false sense of satisfaction when spraying the code with const& everywhere. I saved performance!
As for the "subjective" part, it doesn't really weaken the argument of the FQA. I estimate most of his "subjective" claims are subjectively true for most programmers.
When something is subjectively true for a sufficiently large majority of the relevant group of sentient beings, asserting its truth, period, is common usage.
The FQA states that the C++ doesn't have garbage collection and presents that as a problem. It's a non sequitur. It's like saying "I don't like this knife, I cannot eat soup with it".
I agree with your non sequitur, but I think there is something there nonetheless.
I think Yossi Kreinin's main objection is not the absence of garbage collection in C++, but the fact that so many projects that could use garbage collection, don't.
Like "I need performance!" No you don't. "I really need performance!" My GC is just as fast as your malloc/free. "I don't use malloc/free, I have my own custom allocators, you ignorant Java programmer!" I just use manually managed arrays for that, and enjoy garbage collection for the rest of my data. "My environment can't afford me any GC pause!" My GC hardly pause, and it collects gigabytes of data. "But I know things about my data your GC don't!" OK, now you may have a point.
The performance difference between C++ and a well implemented native language with garbage collection (OCaml, Haskell, Lisp, Go…) is not large. Definitely less than an order of magnitude. Your constraints must be real tight to force you to give up garbage collection.
In the vast majority of projects, not using garbage collection is a problem. If not with the language, at least with the community.
---
I think Yossi Kreinin don't object the knife itself. He objects the fact that people actually try to eat soup with that damn knife, spilling soup and cutting their tongue in the process. Sometimes, we do need sharp edges (for cutting meat). But for much eating activities, sharp edges are just a hindrance.
Not really. It says that having garbage collection is a design choice. What it presents as defective are the implementation of operator overloading and exceptions, and says that having garbage collection would have been a good way to avoid these being defective.
It's pretty well known that C++ suffers from a variety of problems. Many of them have been known about for some time. Despite this, nobody has been able to produce a truly viable alternative.
There have been some encouraging developments, of course. But they've had their own drawbacks that are often worse, in practice, than the problems of C++.
D is an example of this. A lot of new and existing C++ code probably could be written in D instead. But D lacks the widespread adoption and support that C++ offers. This translates into there being fewer third party libraries available, which increases the burden on programmers to an extent that's usually unjustifiable during commercial development And this, in turn, helps prevent the adoption of D.
Rust is another example. It theoretically sounds like it could be a replacement for C++, but that's only true in the far future. The language and its standard libraries have yet to show any real signs of stability. We've been hearing that there may be a 1.0 release at the end of 2014, but time is quickly running out on this. Even then, it will merely be where D is at that point. While there may be a fair number of Rust libraries in existence at this point, many of them have become broken due to language or standard library changes, many are woefully incomplete, and many are totally abandoned.
Then there are Java, C#, Go and others which claim to be successors or potential replacements, and perhaps this is true in a very limited subset of cases. But the remaining situations where they aren't suitable are large in number and quite critical.
Furthermore, we are continually seeing C++ adapt and evolve. It's getting new features and functionality that these competitors are offering, while still usually giving far more freedom and control to programmers, far better performance, far better portability, far greater practicality, and continued use for serious new software projects. These factors combine to make it an even more difficult situation for potential C++ replacements. They just may not bring enough to the table to warrant replacing C++ for a majority of its users or potential users.
"Then there are Java, C#, Go and others which claim to be successors or potential replacements, and perhaps this is true in a very limited subset of cases." If this sentence was true, we'd see only a small adoption of Java and C#, and huge adoption of C++. But I'm afraid you're wrong, and this is exactly reversed now. There's huge adoption of Java/C# used in critical systems in many big companies, while a few niches like embedded programming, games or HFT still use C++ (not exclusively). This is very, very far from "large in number and critical".
"Furthermore, we are continually seeing C++ adapt and evolve."
Indeed. This C++ job trend illustrates this "growing adoption" very clearly: http://www.indeed.com/jobtrends?q=C%2B%2B&l=
Well, pretty much any time that Java, C# or Go are being used, C and/or C++ are also being used. We can't forget that their major implementations are built with C and/or C++, along with much of the underlying software they run upon or interact with.
I don't dispute that languages like Java, C# and Go being widely used. And while the systems built with them may be critical within a very local scope, such as at the company level, pretty much all software of global importance is still implemented in C, C++, or some mix of the two. This is true almost 20 years after Java came on the scene, almost 15 years after C# did, and almost 5 years Go did.
Go is perhaps the only case where this may change, given how its implementors have expressed interest in porting their existing C code to Go. But that still won't change the fact that the operating systems, databases, and other software systems that Go code often interacts with are still very likely to be implemented using C and/or C++.
> Well, pretty much any time that Java, C# or Go are being used, C and/or C++ are also being used. We can't forget that their major implementations are built with C and/or C++, along with much of the underlying software they run upon or interact with.
I don't agree. If someone is programming in Python, they are programming in Python. They aren't programming in C, in addition to Python, just because the VM or whatever is programmed in C. If some language displaces C or C++ in some niche, then it has displaced it, even if the VM of the implementation of the language happens to be written in C or C++. The important distinction, I think, is what people are programming in.
This is like saying that "nothing has proven to be viable alternatives to cement for building houses" when talking about building entire houses with cement, if the foundation of houses are always made up of cement. The fact that the rest of the house can be built with other materials like wood or bricks is a crucial point, in that context.
Are Wikipedia, Twitter, Facebook, LinkedIn or GMail systems of global importance? If they are not, I'm really curious what is your definition of global importance. Their core functionality has been developed in languages such as Java, Scala, PHP and JavaScript. And when looking at the lowest level, everything runs on OSes written in C (Linux, Solaris), webservers written in C or Java (!), and databases / datawarehouses written in C and Java (!), so even your argument that C++ is being used for all the low-level critical stuff is strongly exaggerated.
Sure, as I said, C++ has some place, but nowhere near being the one and only language to implement such stuff, including database engines, webservers and operating systems.
You realize your criticism of D has nothing to do with the language itself, and everything to do with network effects, and first-to-market effect? Of course D lacks the widespread adoptions of C++, it's a newer language! The same goes for your criticism of Rust.
If I were moved by these objections, I would conclude that we shouldn't even try to overthrow established programming languages. Heck why not embrace Status-quo Bias altogether?
About Java & co, you need to realized that most C++ code out there didn't need C++ (or D, or Rust) in the first place. The projects that are (i) very demanding to the CPU and memory, (ii) need a complex solution, and (iii) can't possibly separate a few bottlenecks in C from a high level language with a good FFI (Python, OCaml, Lua, Haskell, Lisp…), are uncommon. Some of those projects have incredible impact, but they are still uncommon.
Java & co are for projects where it was a mistake to use C++ in the first place. They don't compete with C++ on its own turf, they just take away territory C++ should never have controlled.
> You realize your criticism of D has nothing to do with the language itself, and everything to do with network effects, and first-to-market effect? Of course D lacks the widespread adoptions of C++, it's a newer language! The same goes for your criticism of Rust.
Yeah, it's basically a catch-22: lang X is not a viable substitute because it isn't mature enough/not mature enough ecosystem, and continually and relentlessly stating and reinforcing this point will just keep discouraging people from adopting (and indirectly improving) these languages, since clearly... there haven't been any languages that have been able to displace C/++, so what's the point.
And, according to Pacabel, even if you manage to break through some niche with these languages, most underlying software (OSs, VMs, etc.) will still be written in C/++. So if you reimplement the whole bottom of the stack with other systems languages, only then can you talk about displacement, apparently. A tall order.
I have an easy counter to Pacabel's argument: Apple used to use PowerPC. Now they're on X86. People used to use 16bits, then 32bits CPUs. Now they use 64bits CPUs. Operating systems have followed, and soon, programs will as well.
My point is, if you can abstract the underlying architecture, you can replace it. It's difficult because most complex abstractions leak, but it has been done in the past. That Javascript virtual machine written in C++ could be re-written in Rust.
So, even if displacement means "you are not even allowed to use C/C++ as a target language", and "you are not even allowed to use OS services written in C/C++", we can still "displace" C and C++. It won't happen any time soon however. I believe we need to wait for something like mainstream FPGAs.
The problem with current processors and C/C++ is, they tend to be optimized for each other. If instead we had something like an FPGA running at desktop speed, programs would be compiled to logic gates instead of being compiled to assembly. This would dig a grave for C++.
No, D's lack of adoption does involve the language itself to some degree. While the core language itself is better than C++ in some ways, these benefits just aren't compelling enough to exceed the downsides of D, nor do they outweigh the benefits that C++ offers.
And D isn't a new language, by any means. It has been out there for well over a decade now. That should be more than enough time for it to achieve relatively widespread usage, were it to actually offer sufficient benefit over C++ and its other competitors.
I don't know D, so I wouldn't know about it's downsides, besides the one you have spoken of already: lack of adoption. What are the downsides of D that wouldn't go away if it was widely adopted?
You say D is sufficiently old, that it's lack of adoption is significant evidence that we should never adopt it. The problem is, most people think like you do: they wouldn't adopt a language before it has some visible traction. The corollary is, new languages never get widely adopted, unless of course some Big Corporation does massive publicity around it (Java, C#…). The real reason D isn't widely adopted, is not because it's not better than C++. It's because it was not widely adopted in the first place. Textbook chicken and egg.
You speak of benefits and downsides of a language, but what you are really speaking of is the whole ecosystem as it is now. You don't even look at the long term potential.
Also, put yourself in the shoes of a language designer. Say you have a brilliant programming language. Experimental quantitative research has shown with no ambiguity that your language is better than some established, old language in its own niche (20% more productivity, 10% less post-release bugs, same observed runtime speed and memory consumption…). Just one little problem: your language have zero users, and only a little standard library. How would you get people to adopt your new language?
Hint: people won't believe your peer-reviewed experiments. People will refuse to learn a new syntax. People will want to reuse their old code. Even if you come up with an automatic translation tool, people will not trust it. People will say the benefits of the language are outmatched by the drawbacks of its standard library (too small), and of its community (none to speak of). People will be afraid of the required training (even if your research shows productivity benefits after a couple weeks).
How do you fight Status-quo Bias?
Personally, I found only one answer, which unfortunately isn't applicable everywhere: making the new language's implementation so cheap that all it's costs are paid off in a single project. DSLs may do that: with the right tools, a small external DSL can take no more than a couple hundred lines to implement.
C++14 has a good share of the problems of C++98, while adding its own. It's not like C++ ceased to be the most crazily complex and the most deadly trapped language in widespread use.
I'll grant the FQA as such is outdated, but irrelevant? C++ was a huge mistake to begin with, a giant waste of time at the global scale. (Things are different at the individual scale, because network effects.) Having a heavily documented case for the oblivion of C++ is a good thing.
23 comments
[ 3.0 ms ] story [ 57.9 ms ] threadWhich is why Yossi Kreinin called for help about updating the FQA for C++1x and beyond. As he no longer works with C++, both his expertise and the time he can waste on this language are dwindling. http://yosefk.com/blog/c11-fqa-anyone.html
And you can see the same shrewdness, the same "altruism", the same attention to detail, the same tunnel vision – "this shit I'm working on is so important, it deserves all of my mental energy AND the mental energy of my users at the expense of caring about anything else" – throughout the C++ culture. From the boost libraries to "Modern C++ Design" (the author has since repented and moved to D – or did he repent?..) to the justifications for duplicate and triplicate and still incomplete language features to your local C++ expert carrying his crazy libraries and syntactic wrappers and tangling your entire code base in his net.
So true.
In the beginning of my career, I too was drinking the C++ koolaid. I really believed that manual memory management, large and convoluted class hierarchies, obscure template programming, cryptic exception handling, and pointer tinkering was necessary in a language and, of course, to get good performance you had to use C++. What a complete lie.
I still meet programmers who believe that, because it is important. And then you look at what kind of software they are writing, some desktop app or some web service. Huh.
If you look where the C++ community ended up by C++ programming experience over the years is that you should probably avoid all of that if you want bug free code.
It was a complete lie. Fortunately, none of that stuff precludes you from using C++.
The standard library has become so much better then the old days. Now I can even create threads without extra libraries. Unfortunately std types are no longer COW with C++11.
Now if I only can get rid of that awful header file I almost have something that works without too much headache and profanity.
GNU std::string being CoW (still is atm btw) has always been deceitful. The API was simply never designed for that implementation, which resulted in seemingly cheap read-only operations (char x = str[42];) becoming quite expensive.
I'm glad you mentioned actually, since API authors embracing reference semantics through fear of overhead is a great rabbit hole of systemic complexity for C++ developers who are then forced to swim against the tide in the language. Sadly I don't think Rust goes far enough in bringing love to value semantics.
In what other language has so many Stack Overflow threads and blog post been dedicated just how to pass a simple parameter to a function. And with C++11 we have one more way of doing it. It is really mind-boggling.
I never have this problem in other languages and I can do equal the heavy lifting.
And for the C++ programmer it gives a false sense of satisfaction when spraying the code with const& everywhere. I saved performance!
Just bizarre.
http://stackoverflow.com/questions/3171647/errors-in-c-fqa
As for the "subjective" part, it doesn't really weaken the argument of the FQA. I estimate most of his "subjective" claims are subjectively true for most programmers.
When something is subjectively true for a sufficiently large majority of the relevant group of sentient beings, asserting its truth, period, is common usage.
I think Yossi Kreinin's main objection is not the absence of garbage collection in C++, but the fact that so many projects that could use garbage collection, don't.
Like "I need performance!" No you don't. "I really need performance!" My GC is just as fast as your malloc/free. "I don't use malloc/free, I have my own custom allocators, you ignorant Java programmer!" I just use manually managed arrays for that, and enjoy garbage collection for the rest of my data. "My environment can't afford me any GC pause!" My GC hardly pause, and it collects gigabytes of data. "But I know things about my data your GC don't!" OK, now you may have a point.
The performance difference between C++ and a well implemented native language with garbage collection (OCaml, Haskell, Lisp, Go…) is not large. Definitely less than an order of magnitude. Your constraints must be real tight to force you to give up garbage collection.
In the vast majority of projects, not using garbage collection is a problem. If not with the language, at least with the community.
---
I think Yossi Kreinin don't object the knife itself. He objects the fact that people actually try to eat soup with that damn knife, spilling soup and cutting their tongue in the process. Sometimes, we do need sharp edges (for cutting meat). But for much eating activities, sharp edges are just a hindrance.
There have been some encouraging developments, of course. But they've had their own drawbacks that are often worse, in practice, than the problems of C++.
D is an example of this. A lot of new and existing C++ code probably could be written in D instead. But D lacks the widespread adoption and support that C++ offers. This translates into there being fewer third party libraries available, which increases the burden on programmers to an extent that's usually unjustifiable during commercial development And this, in turn, helps prevent the adoption of D.
Rust is another example. It theoretically sounds like it could be a replacement for C++, but that's only true in the far future. The language and its standard libraries have yet to show any real signs of stability. We've been hearing that there may be a 1.0 release at the end of 2014, but time is quickly running out on this. Even then, it will merely be where D is at that point. While there may be a fair number of Rust libraries in existence at this point, many of them have become broken due to language or standard library changes, many are woefully incomplete, and many are totally abandoned.
Then there are Java, C#, Go and others which claim to be successors or potential replacements, and perhaps this is true in a very limited subset of cases. But the remaining situations where they aren't suitable are large in number and quite critical.
Furthermore, we are continually seeing C++ adapt and evolve. It's getting new features and functionality that these competitors are offering, while still usually giving far more freedom and control to programmers, far better performance, far better portability, far greater practicality, and continued use for serious new software projects. These factors combine to make it an even more difficult situation for potential C++ replacements. They just may not bring enough to the table to warrant replacing C++ for a majority of its users or potential users.
"Furthermore, we are continually seeing C++ adapt and evolve." Indeed. This C++ job trend illustrates this "growing adoption" very clearly: http://www.indeed.com/jobtrends?q=C%2B%2B&l=
I don't dispute that languages like Java, C# and Go being widely used. And while the systems built with them may be critical within a very local scope, such as at the company level, pretty much all software of global importance is still implemented in C, C++, or some mix of the two. This is true almost 20 years after Java came on the scene, almost 15 years after C# did, and almost 5 years Go did.
Go is perhaps the only case where this may change, given how its implementors have expressed interest in porting their existing C code to Go. But that still won't change the fact that the operating systems, databases, and other software systems that Go code often interacts with are still very likely to be implemented using C and/or C++.
I don't agree. If someone is programming in Python, they are programming in Python. They aren't programming in C, in addition to Python, just because the VM or whatever is programmed in C. If some language displaces C or C++ in some niche, then it has displaced it, even if the VM of the implementation of the language happens to be written in C or C++. The important distinction, I think, is what people are programming in.
This is like saying that "nothing has proven to be viable alternatives to cement for building houses" when talking about building entire houses with cement, if the foundation of houses are always made up of cement. The fact that the rest of the house can be built with other materials like wood or bricks is a crucial point, in that context.
Sure, as I said, C++ has some place, but nowhere near being the one and only language to implement such stuff, including database engines, webservers and operating systems.
If I were moved by these objections, I would conclude that we shouldn't even try to overthrow established programming languages. Heck why not embrace Status-quo Bias altogether?
About Java & co, you need to realized that most C++ code out there didn't need C++ (or D, or Rust) in the first place. The projects that are (i) very demanding to the CPU and memory, (ii) need a complex solution, and (iii) can't possibly separate a few bottlenecks in C from a high level language with a good FFI (Python, OCaml, Lua, Haskell, Lisp…), are uncommon. Some of those projects have incredible impact, but they are still uncommon.
Java & co are for projects where it was a mistake to use C++ in the first place. They don't compete with C++ on its own turf, they just take away territory C++ should never have controlled.
Yeah, it's basically a catch-22: lang X is not a viable substitute because it isn't mature enough/not mature enough ecosystem, and continually and relentlessly stating and reinforcing this point will just keep discouraging people from adopting (and indirectly improving) these languages, since clearly... there haven't been any languages that have been able to displace C/++, so what's the point.
And, according to Pacabel, even if you manage to break through some niche with these languages, most underlying software (OSs, VMs, etc.) will still be written in C/++. So if you reimplement the whole bottom of the stack with other systems languages, only then can you talk about displacement, apparently. A tall order.
My point is, if you can abstract the underlying architecture, you can replace it. It's difficult because most complex abstractions leak, but it has been done in the past. That Javascript virtual machine written in C++ could be re-written in Rust.
So, even if displacement means "you are not even allowed to use C/C++ as a target language", and "you are not even allowed to use OS services written in C/C++", we can still "displace" C and C++. It won't happen any time soon however. I believe we need to wait for something like mainstream FPGAs.
The problem with current processors and C/C++ is, they tend to be optimized for each other. If instead we had something like an FPGA running at desktop speed, programs would be compiled to logic gates instead of being compiled to assembly. This would dig a grave for C++.
And D isn't a new language, by any means. It has been out there for well over a decade now. That should be more than enough time for it to achieve relatively widespread usage, were it to actually offer sufficient benefit over C++ and its other competitors.
You say D is sufficiently old, that it's lack of adoption is significant evidence that we should never adopt it. The problem is, most people think like you do: they wouldn't adopt a language before it has some visible traction. The corollary is, new languages never get widely adopted, unless of course some Big Corporation does massive publicity around it (Java, C#…). The real reason D isn't widely adopted, is not because it's not better than C++. It's because it was not widely adopted in the first place. Textbook chicken and egg.
You speak of benefits and downsides of a language, but what you are really speaking of is the whole ecosystem as it is now. You don't even look at the long term potential.
Also, put yourself in the shoes of a language designer. Say you have a brilliant programming language. Experimental quantitative research has shown with no ambiguity that your language is better than some established, old language in its own niche (20% more productivity, 10% less post-release bugs, same observed runtime speed and memory consumption…). Just one little problem: your language have zero users, and only a little standard library. How would you get people to adopt your new language?
Hint: people won't believe your peer-reviewed experiments. People will refuse to learn a new syntax. People will want to reuse their old code. Even if you come up with an automatic translation tool, people will not trust it. People will say the benefits of the language are outmatched by the drawbacks of its standard library (too small), and of its community (none to speak of). People will be afraid of the required training (even if your research shows productivity benefits after a couple weeks).
How do you fight Status-quo Bias?
Personally, I found only one answer, which unfortunately isn't applicable everywhere: making the new language's implementation so cheap that all it's costs are paid off in a single project. DSLs may do that: with the right tools, a small external DSL can take no more than a couple hundred lines to implement.
I'll grant the FQA as such is outdated, but irrelevant? C++ was a huge mistake to begin with, a giant waste of time at the global scale. (Things are different at the individual scale, because network effects.) Having a heavily documented case for the oblivion of C++ is a good thing.