> µTorrent is written in C++, and you could never, ever, make it so fast and small using any other language.
That is not a reasonable claim.
The article mentions C, but there are a number of languages that could ostensibly produce a binary of a similar size and efficiency. Rust comes to mind.
True, but at the time of writing, Rust was not available, yet. Can you think of another language? Much of the excitement for Rust comes because it really is the first language that tries to beat C++ (and C) at it's own game.
To be fair, Delphi was pretty hard to get down to that kind of compactness because of dragging in the VCL as a baseline.
You could technically program without it in standard event loop, but then the code would have been unfamiliar enough to other Delphi developers to perpetuate some of the same issues.
Delphi picked up more people from VB and Powerbuilder than it did from TPW, I think.
I got my professional start using Delphi, but never got the impression that many of my colleagues knew TPW well.
Of the ones that didn't come from a database or 4GL background, most of us had used BCW for Windows coding and then switched back to Pascal when it became commercially viable to get a job in it. Borland Pascal didn't exactly have a ton of play in 1995. So it's true that they would've understood basic Petzold-style loops, but it would've been a bit surprising in Delphi.
Later, most of the people I knew using Delphi didn't know bare Windows programming at all, since MFC had fully taken hold for people from that background.
I was also under the impression that OWL was quite dominant, but I admit that I only passed through it briefly between Turbo Vision and VCL.
Yes, without C++, µTorrent could never have packed so many annoying "meet random super models and have sex!" ads into the ap. It just would have been impossible with something like java.
>But for some kinds of applications it seems that the only viable options are still C and C++ ... and you could never, ever, make it so fast and small using any other language. C++ and C are the only options you have here.
Most Go apps can get better than advanced Java GC level allocation-memory performance simply by applying "sync.Pool" (http://golang.org/pkg/sync/#Pool) on applicable pain points.
Its also worth mentioning using a custom allocator + mmap is possible in Go if you really needed it.
Go is also better than Java about using stack allocation for objects.
You want evidence that a object pool with thread-local caching is faster than a garbage collector?
Barring major implementation mistakes this should be self-evident, but you could easily write some benchmarks to verify. Its worth noting that if the Java GC was good enough people would not bother to write object pools in Java- but they do. And Go has a very advanced GC/mutliprocessor aware object pool implementation built in its stdlib.
In an typical object pool only allocation up to the peak concurrent demand for the given object type will ever be allocated and the kicker is that allocation will only happen once. Adding thread-local caching means that that will scale well on multiprocessor systems.
TL;DR: A system that does not generate garbage is going to be faster than a system that does. My argument is that effective use of a good object pool implementation in Go is faster than even a more advanced garbage collector would be.
Another weak point of Go for high-performance computing (besides the garbage collector, which is indeed making huge strides), is the compiler.
Modern C++ compilers do auto-vectorization, offer OpenMP, etc. Of course, you can work around this by writing your numerical code in C or C++, let your C/C++ compiler do the work and bind from cgo.
Another shortcoming of Go is that it cannot be used for building non-Go libraries. First of all because the defacto compiler cannot create shared libraries, secondly, because having a garbage collector gives ownership difficulties once you start binding against another language with a garbage collector.
I will not repeat the usual generics stuff, except that lots of optimizations in C++ code rely on generics (e.g. algorithm selection based on the data type or data type properties).
(No, I am not starting Go bashing season ;), I like Go a lot and it can be used to replace C++ in many projects. Just stating the weak points when coming from C++.)
Go and Rust may be alternatives theoretically, but can you create rich cross platform GUI applications that utilize OpenGL or other fast drawing libraries with either?
That is one of the primary domains of C++ - e.g. photoshop and similar tools.
Go seemed more oriented towards server programming.
This is totally possible in Rust. The biggest problem with Rust is its immaturity, but give it a few years and it'll be a contender for these types of applications. I can't speak for Go.
For the "some kinds" of applications implicitly under discussion, the ones where even in 2009 you'd be looking at C or C++ because, say, Python simply would not do at all, no. It IMHO has a really compelling bang-for-the-buck on the ease-of-use vs. performance, but it is not 100% tilted towards the performance or control side, which makes it unsuitable when you really need those thing. I think it's taking off because it has substance and not just hype, but look at all the "we switched to Go and we love it" posts and you'll see a pattern; they're mostly right in the domain that Go was basically written for, scalable network servers.
The thing that may replace C and C++ right in the niches that are keeping those now-ancient languages current is probably Rust. If successful, Rust will grow beyond that, but it's the only thing squarely pointed at C and C++ right now that seems to have the momentum behind it. Though if you want something right now, you can also try D.
I'm working on a media library at the moment and it doesn't look like it would be an option.
The main reasons.
*GC is a non-starter. An HD frame buffer is around 3MB, a 4K buffer is around 13MB. Letting a GC manage your buffers will lead to heap fragmentation and bring down 32-bit builds relatively quickly.
*Similarly you don't want to copy these things unless you have to so a strategy where each filter is responsible for its own buffers will result in roughly a 3x factor in memory bandwidth.
*All of the downstream software is written in C. So just to get it into GO I either need to do another memcpy or use unsafe stuff in order to deal with it nativly in Go. This along with the above means that I would be looking at 2GB/s of memory bandwidth per stream instead of 500MB/s for a 4K stream.
*My upstream targets include software written in Python and C#. Go appears to assume that it owns main, which is obviously a problem.
Go can pass around byte buffers without copying them... a core use case for its core functionality as a network server. The real problem you'd hit with frame processing in Go is that it doesn't give you access to SIMD, nor does it have a nice GPU connection for computation.
I like Go, but I don't really consider myself an "advocate", and part of that is not overpromising to people. If you've got really heavy-duty computational needs, like in science or graphics, it's a bad choice right now, and I expect it to remain so for the forseeable future because it's not a core concern of the devs, and I'm pretty sure they'd view it as dilution of their goals and value proposition. (Correctly, I might add.)
If C and C++ were the only options, then Go is probably not a viable alternative.
Reasons why C and C++ are the only options might include:
- small executable size. Hello world in Go is over a megabyte
- real-time without GC pauses
- first class native bindings to a certain third party library
That being said, Go is certainly taking market share from applications that traditionally would be written in C/C++. Take Docker, for example. It theoretically could be written in any language that can do networking and Linux syscalls, but pre-golang C or C++ probably would have been the best choice.
I personally see Go as more of a Java killer than a C++ alternative.
Go isn't (and probably will never be) a viable alternative for most of the use cases where you'd want C/C++:
1. Embedded, real-time, kernel: As a GC language which is not meant to write close-to-the-metal code and produces rather bloated binaries (especially compared to C), Go has no chance here. This trinity is still very much the sole territory of C where even C++ seldom dares to tread.
2. Truly cross-platform (not just Windows/Linux/Mac) performance-sensitive libraries that need to be callable (using bindings) from a wide range of programming languages (including C). This is a very common but often neglected class of software where C/C++ reign supreme. Libraries need lots of flexibility in terms of ABI support (e.g. support linking with different C stdlibs) and deployment (e.g. dynamic libraries, which Go, AFAIK, still doesn't support).
3. Complex and lightweight GUI apps with high performance: This is the main class of application mentioned in the blog post. While there are some Go bindings to popular GUI libraries such as Qt and GTK, I'm not sure if their mature enough. Using Qt directly from C++ still seems like the path of least resistance to me. As for lightweight apps, Go apparently still has some work to do about the binary sizes.
4. Web Servers: This is where Go should shine! Programming a concurrent web server using Goroutines should be a breeze, and considering most web servers are still written in C, we would be relieved of the nightmare that is string manipulation in C. But right now, there's still doesn't seem to be any Go equivalent of nginx in development. Go is probably getting mature enough, but I think that if actually squeezing every last ounce of performance is your goal, it still can't beat nginx. For instance, nginx employs many tricks to optimize its memory allocation pattern specifically for the task it was meant to do, and I find it hard to believe that any one size fits all GC, no matter how intelligent, can get the same performance.
" But right now, there's still doesn't seem to be any Go equivalent of nginx in development. Go is probably getting mature enough, but I think that if actually squeezing every last ounce of performance is your goal, it still can't beat nginx."
There's no nginx in development because the built-in net/http library is actually pretty close to it already. Nginx beats it, but only by something like 25-50%, and if you compare the nginx source code to the net/http source code you'll see why nginx is going to likely retain that lead and Go isn't interested in the code quality tradeoff it would take to catch up to nginx. If you ever need an example of C used as "portable assembler", cite the core loop code of nginx.
I'll keep saying it: give me a modern language that is cross platform, results in reasonably sized code footprints, is fast, and that can be used to ship code on all the major OSes, and I'll switch. Until then C/C++ is the only way to achieve that.
It's analogous to the situation with JavaScript on the web. JavaScript is the language of the web because JavaScript is the language of the web. C/C++ is the language of systems because C/C++ is the language of systems.
Besides the aforementioned Rust, I think Nim's got a lot of potential here. And although I'm not a fan, does Go not fit the bill for you? Of the three languages I mentioned, it's the only one that everyone agrees is production ready.
Don't mix the two together. C is great for systems and some application programming, C++ is rubbish.
There was one brief stretch in history around 1994-1998 where C++ was the best choice for application level programming. And even then only a very narrow type of app programming.
Before that brief timeframe and since then it has been a poor choice for every single type of programming. There are better choices in all cases. It has no niche anymore where it is the best fit, not anywhere.
Does it matter? std::string is safer than the dog's breakfast that is strcpy/strncpy/lstrncpy/strncpy_s/mempcpy on any platform. And static_cast<myclass> beats (void*) everywhere - Linux, Windows, OSX, Android...
Before that brief timeframe and since then it has been a poor choice for every single type of programming. There are better choices in all cases.
For memory-sensitive applications where time-amortization hurts (and this turns out to be pretty much every application that anyone wants to run on their local computer), C++ is still king and is still the best choice for the job. Everyone hates C++, and yet every desktop application in widespread use is built with it. I wonder why? Is it really just inertia?
Java, C# - programmers are stuck with a runtime that literally consumes 10x ram as equivalent C++ software. Do you like switching applications on your Android phone and having every other process pushed out of memory? I didn't think so. And while both environments are now offering ahead-of-time compilation, the CLR/JVM runtimes are still much larger than what C++ consumes and you give up the only chance of matching C++'s runtime CPU performance (harvesting runtime profiling to inform the JIT).
Golang - a huge step in the right direction, this will probably end C++ use on servers and hosts eventually. It still can't match C++'s runtime performance, but who cares in a host environment. Still, garbage collection makes it unsuitable for local applications where users notice micro-pauses due to garbage collection. Nothing is worse than going into alpha with 10 P0 bugs complaining about 'micro-pauses' and finding out it's because of something you can't change in the runtime.
D - truly a better C++ than C++. But no one uses it.
Rust - our best hope so far, but the compiler and standard library aren't there yet. You still can't program a web server, for example, without manually handling unsafe objects. Even then its going to be years before there are libraries available that are of similar quality to things like Qt. How do make a GUI application in Rust in 2015?
C - I hope you like (void*) and all of the fun runtime bugs that introduces.
But seriously - "There are better choices in all cases"? Like what?
> Everyone hates C++, and yet every desktop application in widespread use is built with it. I wonder why? Is it really just inertia?
First off, that is incorrect. You underestimate the number of VB, C#, and other apps, not to mention OSX based apps. Most business apps are either in Java on the backend or if they aren't web based they are in proprietary languages and frameworks that likely use a mix of C and C++ at the core. They are mostly shit nowadays though which is why everyone is re-writing them in the Cloud. They're unmaintainable.
But yes there are a lot of high visibility popular desktop apps in C++ and yes, it is just inertia. When were all of those desktop apps you're thinking of first built (or came of age)? The early 90s! Microsoft Office, the Adobe suite, Visio (bought out by Microsoft), desktop databases, etc.
That was the age of the desktop and briefly, C++ was the best choice. I'll grant you a few very small niches still exist and they are in the desktop domain e.g. web browsers and very complex image editors. But how many people are writing browsers? And simpler image editors are better off being mostly in Objective-C or C# (minus some core libraries which are best off in C).
The "desktop" market is considerably larger than you think it is. It includes a vast array of professional apps for things like CAD/CAM, SPICE, numeric simulation and analysis, graphics and "real" word processing, management of large data sets, industrial control software, heavy clients for complex remote control applications, typesetting, etc. along with the standard web and software engineering use cases.
These are not "legacy" apps. They are huge cutting-edge professional suites that drive massive chunks of the economy and contain some of the most complex and challenging computer code ever written. We're talking about stuff like Monte Carlo analysis and genetic algorithm generation of physical machines, simulation of massive electronic circuits, etc... some of these things are the closest thing software engineering has to modern wonders of the world.
Go try re-implementing SolidWorks in JavaScript as a client/server app or for Android or iOS and then tell me desktop is dead. Then there's the whole issue of security, privacy, and data ownership. Cloud demands a lot of trust in the provider, and mobile treats user data with something near contempt (apps "own" their files, etc.). There is absolutely no way I am writing a novel or a Ph.D thesis in the cloud or on a mobile device. I'm doing it on a machine I control with a backup system I control where an app being pulled from an app store or a cloud provider experiencing a hack/failure won't obliterate my two years of work.
Granted that such things can be written now in languages other than C++, and sometimes can even be shipped in those languages without torturing the user with secondary runtime installs and other insults. But C++ still really rules here. You write it, you build it, and you ship it. Bloat is fairly minimal. Even if you use Qt the bloat is still a lot less than Jabba.
I do think the majority of these fall into the "first built in the 90s" category and while they aren't legacy they do have a legacy codebase to deal with.
Good examples though. If you were building them from scratch, I would still question the choice of C++ for these as opposed to C#, Objective-C native UI layers combined with a C core.
Before that brief timeframe and since then it has been a poor choice for every single type of programming. There are better choices in all cases.
I'll grant you a few very small niches still exist and they are in the desktop domain
Show me a popular desktop app written in something other than C++. Even when developers have tried to write a desktop app in something other than C++ (like Evernote on Windows) it was deemed a failure and was re-implemented in C++.
And you still haven't presented a compelling argument for choosing C over C++. C++ IS C, but with extra stuff that makes it better, like generics, custom types, alternatives to C's nuclear-powered casting, strings that don't blow up in your face, etc, etc. Why should a core library only be written in C?
Show me non-legacy desktop apps that were written in the past few years that are in C++. I believe the majority of ones I use on the Mac were written in Objective-C. If they aren't using specialized legacy libraries (e.g. image processing) I bet I don't have a single one that is in C++ other than image editing and browsing.
I'm not sure the state of consumer Windows apps but almost all desktop business apps are in C# or VB. Unless of course they are accessing legacy C++ stuff.
The post you're replying to just did: Evernote 4 for Windows was rewritten from scratch in C++ (with WTL). It was C#/WPF before.
I can give you a few more: Chrome (not entirely new, but still the newest major browser around), Sublime Text (compare its performance with Atom to realize the strengths of C++), GoldenDict, Scan Tailor.
Actually, I've tried thinking of new Desktop apps which came out in the last 5 years and there weren't many. Developing new desktop apps is just not as popular as it used to be 10 years ago. It has a lot to do with the rising prominence of web and mobile apps, but this also has something to do with C++, when I think about it.
Writing a cross-platform web app with acceptable performance is easier than writing a desktop app with the same properties, since you'd almost certainly need to use C++ to get an app with the same properties on the desktop.
With web apps you essentially get cross-platform for free (at least since the days of jQuery and IE shims) and the performance is not stellar, but at least it's not worse than all the other web apps, so it matches your users expectations.
On the desktop, you usually get three routes:
1. C++ app with a cross platform GUI toolkit (probably Qt, since GTK user experience is usually horrible on anything other than *NIX) or an abstraction layer like wxWidgets.
2. Cross-platform Java or Mono/.NET app with cross platform GUI toolkit. There are occasional exceptions, but these apps generally tend to be bloated or hard to install, and never match the snappiness of native apps.
3. Write a separate native front-end for each platform, using its own native GUI toolkit. This usually means C with @WinForms/WPF for Windows and Objective-C with Cocoa for Mac. If you have a shared backend, you would usually still be forced to use C or C++ to make it usable with both runtimes.
Another huge problem with all of the above alternatives is deployability, upgrade cycles, and general "installability" UX issues.
Runtimes like Java that want to install the runtime as a separate package on the system which must be separately approved and separately maintained. This also results in loads of different versions of the same runtime installed on the same machine.
As an alternative, the app author may sometimes bundle the runtime. Result: package bloat.
As another alternative, the app author may statically link the runtime. Result: binary bloat.
So your choice is between included bloat and secondary install bloat, not to mention version management nightmares and conflicts and other horrors.
Java's deployment issues are what killed it as a platform for shipping desktop apps. I tried to ship a desktop app with Java once, and never will again. C# is a bit better as it's generally installed on all Windows machines, but is MS only so is not portable.
C++ = portable, not horribly bloated, deployable, update-able, and mature.
There aren't any alternatives. This is not really a technical problem... it's just that nobody has gotten their act together to ship something that addresses these concerns. A lot of programmers don't seem to understand installability and ship things that demand follow-on package dependencies and other bloat. General rule: every installation step or sub-package exponentially increases the difficulty of deployment and maintenance.
Another problem is that these languages try to do too much. They try to be languages and runtimes, which in practice means they're OSes-within-the-OS. That means bloat is pretty unavoidable. A JVM is functionally not far from a VM running in a hypervisor, so you might as well just ship apps with Vagrant or something.
1994-1998 was a bad time for C++. Stepanov had just come along with the STL idea, and there were various competing implementations of it. And I don't think I need to say anything more about the travesty of MFC other than to acknowledge its mere existence.
C++14 (the latest standard) is a far better language than C++ in the '90s, and it really does beat C when it comes to abstraction capabilities, type safety, and standard library functionality. C++11 also defined a standardized memory model which is extremely useful for writing multithreaded code.
Yes, C++ is not perfect -- the C++ standard library lacks a lot of functionality found in the libraries of other languages; there is a lot of complexity in the language that one must master to really "know" C++; the language itself has dark corners and disappointments; and so on. No language is perfect, and every language permits bad code.
I've been working with C++ full-time for the past three years. I didn't know much about the language before then (I was a "C 43var!" guy), but had heard all the horror stories about it. Now, I'm convinced that it's probably the best general purpose programming language available to date. It combines the full power of the machine with very expressive abstraction capabilities. Having seen what can be done with C++, I decided to study harder and try to master it.
I think this last point is ultimately what puts people off, and leads to a lot of FUD about C++ -- it takes hard work to master the language and the tools to work with it. Nobody really wants to do that, not when there are seemingly viable, and easier, alternatives. Instead, people are more willing to invest huge amounts of effort and money to try to scale up those alternatives if it means they can avoid the complexity of a language like C++. That's fine, I guess, we all have to make the appropriate engineering trade-offs, it's just unfortunate that many people fall into extremism about it in order to justify their attempt to simplify the reality of computing (which is actually considerably complex).
> C is great for systems and some application programming, C++ is rubbish
This is a bizarre claim. C++ has its problems, but the fact that it allows zero-overhead abstractions over common low-level boilerplate is a seriously non-trivial advantage over C in most areas where C is otherwise a good fit. What compelling advantage does C retain over C++? Faster compiles and being easier to learn are nice and all, but hardly slam-dunks.
If server-side (web)apps were written in C++ instead of Ruby/Python/..., I believe they can sustain much more users before they need to consider horizontal scalability seriously, since we can fully utilize the machine in C++. AFAICT it is nearly impossible to optimize to the level of cache efficiency (and etc.) in Ruby/Python/..., and a distributed system is much harder to cope with, and when you need to work on that, the choice of programming language becomes less important.
However, building a not-so-bad prototype in Ruby/Python/... is much easier. So probably something needs to be done (e.g. "frameworks", libraries, tutorials) for C++.
[EDIT] C++ (templates) can provide abstractions with zero run-time cost. C doesn't have such abstractions. Ruby/Python/... don't have such low cost.
But most (or at least a huge percentage of) server-side web apps are written in Java. While I don't love Java it is better in every way shape and form for server-side web apps than C++.
True, but early C++ libraries were tainted with a C mindset so althouth C++ could provide a Java like confort, you were stuck with C with classes libraries instead.
Just look at MFC vs OWL vs VCL, or Visual C++ vs C++ Builder.
This really seems like the sweet-spot for Go - nearly the same runtime performance as C/C++, and no single-threaded memory leaks or stomps. Low memory overhead, fast startup time, and the time amortization inherent in garbage collection doesn't matter a whit.
Now is a good time to bash C++. The alternatives are better than they were in 2009. For web stuff, Go is a good alternative. Rust is starting to look like a good alternative for low-level code.
The C++ crowd keeps trying to paper over the Mess Inside with templates, but the mold keeps coming through the wallpaper. After dealing with C++ since the mid-1990s, it's time to move on.
There have been good alternatives over the years, but their backing companies failed for other reasons. Xerox had Mesa and Cedar. DEC had Modula 3. Borland had Delphi. None went mainstream outside their niches.
Today, a compiler almost has negative commercial value. It took $20 million to launch Java, and the compiler was given away. The Go and Rust compilers are free. There was a time when a C or C++ compiler cost several hundred dollars. Now, you have to give them away. It's hard to fund development in that environment.
You need to be able to provide a compiler for your language that can beat C++ compilers, while offering for free, because in 2015 almost no one pays for compilers.
So without a strong revenue, it is almost impossible to provide alternatives, hence the status quo doesn't change.
I still don't understand the point that Animats is making - what you've said argues in favor of C++ given that C++ already has multiple high-quality compilers available for it. If revenue is such a big issue, how has the Rust community come so far with their compiler?
Again, maybe I'm being a bit thick here, but I still don't understand the point he's making. First he declares that the alternatives to C++ are better than ever, which I guess is true.
He makes a point about Golang being a great alternative to C++ for web apps. I can't imagine that anyone is actually using C++ for web apps (are they?!?), so I don't see Golang as a C++ alternative so much as I see it as a Java or Ruby alternative. But I guess you could say that Golang is still quite literally a better choice for a webapp than C++ is - for that matter Golang is superior to INTERCAL for webapps too.
Then there's this whole coda to his post where I guess he's trying to make the point that you can't make money selling C++ compilers anymore? Is he just missing the point? C++ compilers are part of an ecosystem - of course you don't make money selling them. Why has Microsoft always nearly given away Visual Studio? Why is Xcode free? Or is Animats making a more subtle argument here that I'm not parsing?
> I can't imagine that anyone is actually using C++ for web apps (are they?!?)
Well, Apache and IIS modules, or web access to embedded devices.
> C++ compilers are part of an ecosystem - of course you don't make money selling them.
It wasn't always like that. Back in the 80's and 90's if you wanted a compiler for any language, including C++, buying was the only option.
I did buy a few of them.
Microsof only offers Visual Studio since the 2005 version, as open source started to make a dent into Windows.
The .NET SDK was the first developer tooling that Microsoft offered for free.
Given the price difference between Macs and PCs, XCode isn't quite free. And you need to pay 100 euros/dolars yearly if you want access to the developer program.
And if you look into the games consoles, embedded market or high performance computing, compilers are still commercial.
But in the desktop and server market, hardly anyone will be willing to pay for compilers in 2015.
* I can't imagine that anyone is actually using C++ for web apps (are they?!?)*
Google is. They need the speed. Why do you think Google is paying for the development of Go? They need a better language for their back-end processing. 2x slower means twice as many acres of data center. C++ is too slow to write and too hard to debug, and Python is too slow to execute. (Google had a project to speed up Python, called Unladen Swallow, but it failed.)
The reason that compilers are free is because they are complements in economic terms. Having good compilers available for free makes CPUs more valuable, that's why Intel & Apple invest millions of dollars every year into compilers. Good compilers make software more valuable, that's why Google, Apple and Mozilla invest millions.
But you're right: compilers almost have negative commercial value. So many deep pockets are spending so much and giving away the results, making it hard to compete.
You can bash C++ all you want yet it is the one language that stands in the middle of high performance and systems development. Somehow all the "alternatives" fail in some part and all you're left with is C++. Rust may be getting there but it will take years until you will program your embedded realtime application in it.
C++ got into this position due to people like me, that were considered hipster back then, by going with that slow molass, full of portability issues trying to implement parts of C++ARM, instead of C.
I did it, because sadly the vendors of the alternatives mentioned by Animats didn't managed to keep their languages up to what the OS vendors were putting on their SDKs.
So stuck between C and C++, at least C++ was already a better alternative than writing plain unsafe C code.
I'd make the argument that Rust is making many of the same mistakes as C++. It's got a kitchen-sink approach that has already accumulated some barnacles, and that ownership system is a mess.
The ownership system, the big innovation in Rust, isn't bad. The type system, macro system, and error handling interact to form a big mess. Exceptions would have been simpler than the mechanisms used to avoid exceptions.
A note on exceptions. Exceptions have a bad reputation in some quarters. They're not in Go, Rust, or C, and they're troublesome in Java and C++. They're successful in Python. Why is this?
It took several go-rounds to make Python exceptions generally useful. Originally, exceptions were just strings. Exceptions became more useful when an standard hierarchy of exceptions was defined and libraries were modified to use it. The Python exception hierarchy has a root of Exception, and one of its subclasses is EnvironmentError. Errors that reflect problems external to the program, such as I/O, network, and external data format errors, are subclasses of EnvironmentError. So if you catch EnvironmentError and report it properly, that covers most common cases. Exceptions not under EnvironmentError generally indicate program bugs, so those are usually allowed to propagate upward to the point where crash-level errors are handled. The default is a program abort and a stack backtrace.
The other problem is getting things closed out properly after an exception. C++ tried doing this by having destructors close things. This works until something goes wrong in a destructor. Exceptions raised within destructors tend to cause problems. This tends to result in ignoring errors at close time. Go's "defer" has the same problem. Calling destructors from a garbage collector is even worse. Microsoft tried to address this in Microsoft Managed C++, resulting in painfully complicated destructor semantics. (Look up "re-animation" for Managed C++, if you like.)
The Python solution was a "with" clause. This is borrowed from Common LISP's "(with-open-file ..) construct. The Python syntax is "with opening expression as object handle :". The opened object is open for the scope of the with clause, and upon exit from the with clause, the "__exit__" method of the object will be called, no matter how the with clause is executed. To make this work, I/O, locks, and database connectors had to be retrofitted with "__exit__" methods. This was done around Python 2.5-2.6; it took a while.
The result is that Python functions that open and close things tend to have this pattern:
def dosomething(args) :
try:
with *thingtoopen* as *handle1* :
with *otherthingtoopen* as *handle2* :
*do work on open things*
except EnvironmentError as message :
*report errors which occurred opening things, working on them, or closing them*
This is reasonably simple, and tends to result in programs that do something reasonable for error conditions. Importantly, even if an exception is raised, the close operations take place. Even the case of a close operation raising an exception is properly handled; the other close operations still take place, but they are aware there's an exception situation. A database connector would do a ROLLBACK instead of a COMMIT in such a situation.
This is probably the direction Rust should have taken. Error handling in Rust requires excessive boilerplate code every place an error can occur. The new Rust error hierarchy scheme [1] is especially verbose.
Python's with has no advantages at all over destructors that I'm aware of (it does have some disadvantages, since it's easy to forget) and I'm curious to ask what you think they are. This may help those of us who are extremely happy with Rust's error handling story better understand your complaints. You keep talking about "excessive boilerplate" and the like, but that simply isn't what I observe in practice--it could certainly be better, but existing solutions are fairly unobtrusive. You also claim that exceptions are "successful" in Python, but I have had just as many issues with exceptions in Python as I have in Java (if not more, because the exceptions are not part of the function signature).
The problems with exceptions are well-documented (they require the programmer to write all his or her code transactionally, leading to so-called exception safety issues). Subclassing doesn't address the major issues of error handling at all, as far as I know, but again--I'd be interested to hear how you feel they are different (Rust already has an IOError that suffices for the cases you seem to be concerned about, but in practice there are many more types of error than that).
Hacker News isn't really a good place to post code, but here's an excerpt of the boilerplate required in Rust code that reads XML to pass I/O, HTTP, and XML parsing errors upward. This, according to the reference above on the new style of error handling, is now the official right way to do it.[1] Works fine. You get to repeat all this each time you define a new result type with possible lower level errors. What's wrong with this picture?
//
// Return type and its error handling
//
pub type FeedResult<T> = Result<T, FeedError>;
/// A set of errors that can occur handling RSS or Atom feeds.
#[derive(Debug, PartialEq, Clone)] // crank out default functions
pub enum FeedError {
/// Error detected at the I/O level
FeedIoError(IoError),
/// Error detected at the HTTP level
FeedHTTPError(hyper::HttpError),
/// Error detected at the XML parsing level
FeedXMLParseError(xml::BuilderError),
/// XML, but feed type not recognized,
FeedUnknownFeedTypeError,
/// Required feed field missing or invalid
FeedFieldError(String),
/// Got an HTML page instead of an XML page
FeedWasHTMLError(String)
}
//
// Encapsulate errors from each of the lower level error types
//
impl error::FromError<hyper::HttpError> for FeedError {
fn from_error(err: hyper::HttpError) -> FeedError {
FeedError::FeedHTTPError(err)
}
}
impl error::FromError<old_io::IoError> for FeedError {
fn from_error(err: IoError) -> FeedError {
FeedError::FeedIoError(err)
}
}
impl error::FromError<xml::BuilderError> for FeedError {
fn from_error(err: xml::BuilderError) -> FeedError {
FeedError::FeedXMLParseError(err)
}
}
impl fmt::Display for FeedError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&FeedError::FeedIoError(ref xerr) => xerr.fmt(f), // I/O error
&FeedError::FeedHTTPError(ref xerr) => xerr.fmt(f), // HTTP error
&FeedError::FeedXMLParseError(ref xerr) => xerr.fmt(f), // XML parse error
&FeedError::FeedUnknownFeedTypeError => write!(f, "Unknown feed type."),
&FeedError::FeedFieldError(ref s) => write!(f, "Required field \"{}\" missing from RSS/Atom feed.", s),
&FeedError::FeedWasHTMLError(ref s) => write!(f, "Expected an RSS/ATOM feed but received a web page \"{}\".", s)
//_(ref xerr) => xerr.fmt(f) // would be convenient, but not allowed in Rust.
}
}
}
You don't have to do any of this. You can just use Box<Error> in your Result and handle all types that implement FromError, if you so choose. You can also decide to do it this way, if you want to have more explicit error messages. Or you can simply forgo all this and return errors explicitly.
I'm frankly not sure why you think this is boilerplate, though: what, indeed, is wrong with this picture? Maybe I'm simply missing the obvious, but this doesn't even seem like that much code to me, especially given that each of your error types would have to be classes in other languages. (BTW, you don't need to prefix all the errors with Feed because they are already namespaced). Once you've written the above, you can simply try! everywhere and get automatic conversions--and you use try! a lot more often than you define new result types.
Your example also looks very much like what I would write in a language like Java, where exceptions are actually part of the signature (which is the approach Rust takes). Perhaps you are talking to the wrong person here, but I have never had an issue with Java's approach to checked exceptions, only the many ways the language provides to undermine them and the difficulty of creating new error types without ADTs.
In any case, you still haven't addressed my remaining questions re: exceptions. We may disagree on whether the above is boilerplate, but given that exceptions have other problems they are still not a drop-in replacement. I think if you consider boilerplate to be the biggest issue in error handling, you and I likely fundamentally disagree.
If you think that Rust is a kitchen sink language or that the ownership system is a mess, then I have to assume that you have neither followed the language through its development nor used it. It catches flak every day for not being a kitchen sink language, and the ownership system is probably the only part of it that's so finely-polished that I have no faults with it.
Now, Rust macros? Those are gross. The module system is love-it-or-hate-it. The syntax could be most charitably described as "classical" and the compiler itself is held together with reams of duct tape. But it's the first language that's attempting to explore this design space in an industrial setting and encounter all the problems therein (for god's sake, they had to reinvent the notion of closures (and even if you superficially believe they're similar to C++11 closures, the mechanisms required to make C++-style closures memory-safe are novel AFAICT)). Despite all of its flaws (and the upcoming 1.0-stable release will have flaws), it's a remarkably worthwhile language to learn and will influence every language to come that cares to call itself a systems programming language, all because the core ownership system has been so long iterated-upon (and even that will continue to see ergonomic improvements as time goes on).
I'm putting together an app where the c++ code is more or less adding a structure over "raw bytes" in memory or on disk. I actually looked at Rust but I can't see how it would help when you want to have all you operations really be a big chunk of already allocated memory.
c++ isn't going to be growing because it's less applicable to the new use cases but I don't think that makes it less applicable to standard use cases.
It depends on how you define "AAA". Any big-name game written before the mid-to-late-90s (Mario, Tetris, etc.) wouldn't have been written in C++. Mobile games (Angry Birds, Candy Crush, etc.) cannot be written in C++ by dint of their platforms. Minecraft, a contender for the best-selling game of all time, is written in Java.
Angry Birds most likely was written (at least partially) in C++ as Rovio has confirmed that they used Box2D, a C++ physics engine, as the engine for Angry Birds.
All the major mobile platforms support C++. Android through the use of the NDK. Windows phone has support C++ since version 8. iOS has supported C++ as long as there has been the app store, either through Objective-C++ or C++ libraries with a C interface.
I'm doing it now for my first Android app and the JNI isn't as bad as I expected. I'm using juce and it has a bunch of macros that reduce the JNI calls down to 1 line, and there are a classes to convert the types. The UI is all in a webview anyway. It took me under two weeks to learn the Android tools and get a pretty significant app ported.
But I was horrified at how bad the tools and emulator are. I spent more time trying to get things to work rather than porting code.
I think people miss the context and subtleties of the Linus Torvalds rants. He was addressing rather idiotic junk on the mailing list about using C++ in the Linux kernel. He was trying to shut down some spergs who wouldn't grasp a more subtle request to not barge in on a decade plus old team of C hackers with tooling discussions.
C++ is a language designed for specific use cases. If you want a systems level language with extremely low cost abstractions and write high performance, or low service-latency applications or applications that run on devices where you care about power consumption, memory utilized, etc, then C++ is one of the languages that you could consider.
Its pretty bizarre to compare it to python or ruby or perl. Yes, you should use other languages if you can. C++ is used when you cant.
99 comments
[ 6.1 ms ] story [ 175 ms ] threadThat is not a reasonable claim.
The article mentions C, but there are a number of languages that could ostensibly produce a binary of a similar size and efficiency. Rust comes to mind.
All strong in the 90's, sadly the market went somewhere else.
Only Ada seems to survive, but in its own area, high integrity computing.
You could technically program without it in standard event loop, but then the code would have been unfamiliar enough to other Delphi developers to perpetuate some of the same issues.
Not everyone was using OWL all the time.
I got my professional start using Delphi, but never got the impression that many of my colleagues knew TPW well.
Of the ones that didn't come from a database or 4GL background, most of us had used BCW for Windows coding and then switched back to Pascal when it became commercially viable to get a job in it. Borland Pascal didn't exactly have a ton of play in 1995. So it's true that they would've understood basic Petzold-style loops, but it would've been a bit surprising in Delphi.
Later, most of the people I knew using Delphi didn't know bare Windows programming at all, since MFC had fully taken hold for people from that background.
I was also under the impression that OWL was quite dominant, but I admit that I only passed through it briefly between Turbo Vision and VCL.
Still, good point!
And I think you mean Modula-3, not Modula-2.
It's kind of a shame. I'm a huge fan of languages like D, Modula-3, and Delphi, and I'm really disappointed they never took off.
Modula-3 was hardly used outside DEC, while Modula-2 had big use in Europe.
Is Go a viable alternative now?
Its also worth mentioning using a custom allocator + mmap is possible in Go if you really needed it.
Go is also better than Java about using stack allocation for objects.
Barring major implementation mistakes this should be self-evident, but you could easily write some benchmarks to verify. Its worth noting that if the Java GC was good enough people would not bother to write object pools in Java- but they do. And Go has a very advanced GC/mutliprocessor aware object pool implementation built in its stdlib.
In an typical object pool only allocation up to the peak concurrent demand for the given object type will ever be allocated and the kicker is that allocation will only happen once. Adding thread-local caching means that that will scale well on multiprocessor systems.
TL;DR: A system that does not generate garbage is going to be faster than a system that does. My argument is that effective use of a good object pool implementation in Go is faster than even a more advanced garbage collector would be.
Modern C++ compilers do auto-vectorization, offer OpenMP, etc. Of course, you can work around this by writing your numerical code in C or C++, let your C/C++ compiler do the work and bind from cgo.
Another shortcoming of Go is that it cannot be used for building non-Go libraries. First of all because the defacto compiler cannot create shared libraries, secondly, because having a garbage collector gives ownership difficulties once you start binding against another language with a garbage collector.
I will not repeat the usual generics stuff, except that lots of optimizations in C++ code rely on generics (e.g. algorithm selection based on the data type or data type properties).
(No, I am not starting Go bashing season ;), I like Go a lot and it can be used to replace C++ in many projects. Just stating the weak points when coming from C++.)
That is one of the primary domains of C++ - e.g. photoshop and similar tools.
Go seemed more oriented towards server programming.
The thing that may replace C and C++ right in the niches that are keeping those now-ancient languages current is probably Rust. If successful, Rust will grow beyond that, but it's the only thing squarely pointed at C and C++ right now that seems to have the momentum behind it. Though if you want something right now, you can also try D.
I like Go, but I don't really consider myself an "advocate", and part of that is not overpromising to people. If you've got really heavy-duty computational needs, like in science or graphics, it's a bad choice right now, and I expect it to remain so for the forseeable future because it's not a core concern of the devs, and I'm pretty sure they'd view it as dilution of their goals and value proposition. (Correctly, I might add.)
Reasons why C and C++ are the only options might include:
- small executable size. Hello world in Go is over a megabyte
- real-time without GC pauses
- first class native bindings to a certain third party library
That being said, Go is certainly taking market share from applications that traditionally would be written in C/C++. Take Docker, for example. It theoretically could be written in any language that can do networking and Linux syscalls, but pre-golang C or C++ probably would have been the best choice.
I personally see Go as more of a Java killer than a C++ alternative.
1. Embedded, real-time, kernel: As a GC language which is not meant to write close-to-the-metal code and produces rather bloated binaries (especially compared to C), Go has no chance here. This trinity is still very much the sole territory of C where even C++ seldom dares to tread.
2. Truly cross-platform (not just Windows/Linux/Mac) performance-sensitive libraries that need to be callable (using bindings) from a wide range of programming languages (including C). This is a very common but often neglected class of software where C/C++ reign supreme. Libraries need lots of flexibility in terms of ABI support (e.g. support linking with different C stdlibs) and deployment (e.g. dynamic libraries, which Go, AFAIK, still doesn't support).
3. Complex and lightweight GUI apps with high performance: This is the main class of application mentioned in the blog post. While there are some Go bindings to popular GUI libraries such as Qt and GTK, I'm not sure if their mature enough. Using Qt directly from C++ still seems like the path of least resistance to me. As for lightweight apps, Go apparently still has some work to do about the binary sizes.
4. Web Servers: This is where Go should shine! Programming a concurrent web server using Goroutines should be a breeze, and considering most web servers are still written in C, we would be relieved of the nightmare that is string manipulation in C. But right now, there's still doesn't seem to be any Go equivalent of nginx in development. Go is probably getting mature enough, but I think that if actually squeezing every last ounce of performance is your goal, it still can't beat nginx. For instance, nginx employs many tricks to optimize its memory allocation pattern specifically for the task it was meant to do, and I find it hard to believe that any one size fits all GC, no matter how intelligent, can get the same performance.
There's no nginx in development because the built-in net/http library is actually pretty close to it already. Nginx beats it, but only by something like 25-50%, and if you compare the nginx source code to the net/http source code you'll see why nginx is going to likely retain that lead and Go isn't interested in the code quality tradeoff it would take to catch up to nginx. If you ever need an example of C used as "portable assembler", cite the core loop code of nginx.
No? Too bad.
Okay, I'm in with the rest. I'm spoiled, used to seeing the year in the titles of HN posts when it's old. My bad.
It's analogous to the situation with JavaScript on the web. JavaScript is the language of the web because JavaScript is the language of the web. C/C++ is the language of systems because C/C++ is the language of systems.
There was one brief stretch in history around 1994-1998 where C++ was the best choice for application level programming. And even then only a very narrow type of app programming.
Before that brief timeframe and since then it has been a poor choice for every single type of programming. There are better choices in all cases. It has no niche anymore where it is the best fit, not anywhere.
For memory-sensitive applications where time-amortization hurts (and this turns out to be pretty much every application that anyone wants to run on their local computer), C++ is still king and is still the best choice for the job. Everyone hates C++, and yet every desktop application in widespread use is built with it. I wonder why? Is it really just inertia?
Java, C# - programmers are stuck with a runtime that literally consumes 10x ram as equivalent C++ software. Do you like switching applications on your Android phone and having every other process pushed out of memory? I didn't think so. And while both environments are now offering ahead-of-time compilation, the CLR/JVM runtimes are still much larger than what C++ consumes and you give up the only chance of matching C++'s runtime CPU performance (harvesting runtime profiling to inform the JIT).
Golang - a huge step in the right direction, this will probably end C++ use on servers and hosts eventually. It still can't match C++'s runtime performance, but who cares in a host environment. Still, garbage collection makes it unsuitable for local applications where users notice micro-pauses due to garbage collection. Nothing is worse than going into alpha with 10 P0 bugs complaining about 'micro-pauses' and finding out it's because of something you can't change in the runtime.
D - truly a better C++ than C++. But no one uses it.
Rust - our best hope so far, but the compiler and standard library aren't there yet. You still can't program a web server, for example, without manually handling unsafe objects. Even then its going to be years before there are libraries available that are of similar quality to things like Qt. How do make a GUI application in Rust in 2015?
C - I hope you like (void*) and all of the fun runtime bugs that introduces.
But seriously - "There are better choices in all cases"? Like what?
First off, that is incorrect. You underestimate the number of VB, C#, and other apps, not to mention OSX based apps. Most business apps are either in Java on the backend or if they aren't web based they are in proprietary languages and frameworks that likely use a mix of C and C++ at the core. They are mostly shit nowadays though which is why everyone is re-writing them in the Cloud. They're unmaintainable.
But yes there are a lot of high visibility popular desktop apps in C++ and yes, it is just inertia. When were all of those desktop apps you're thinking of first built (or came of age)? The early 90s! Microsoft Office, the Adobe suite, Visio (bought out by Microsoft), desktop databases, etc.
That was the age of the desktop and briefly, C++ was the best choice. I'll grant you a few very small niches still exist and they are in the desktop domain e.g. web browsers and very complex image editors. But how many people are writing browsers? And simpler image editors are better off being mostly in Objective-C or C# (minus some core libraries which are best off in C).
These are not "legacy" apps. They are huge cutting-edge professional suites that drive massive chunks of the economy and contain some of the most complex and challenging computer code ever written. We're talking about stuff like Monte Carlo analysis and genetic algorithm generation of physical machines, simulation of massive electronic circuits, etc... some of these things are the closest thing software engineering has to modern wonders of the world.
Go try re-implementing SolidWorks in JavaScript as a client/server app or for Android or iOS and then tell me desktop is dead. Then there's the whole issue of security, privacy, and data ownership. Cloud demands a lot of trust in the provider, and mobile treats user data with something near contempt (apps "own" their files, etc.). There is absolutely no way I am writing a novel or a Ph.D thesis in the cloud or on a mobile device. I'm doing it on a machine I control with a backup system I control where an app being pulled from an app store or a cloud provider experiencing a hack/failure won't obliterate my two years of work.
Granted that such things can be written now in languages other than C++, and sometimes can even be shipped in those languages without torturing the user with secondary runtime installs and other insults. But C++ still really rules here. You write it, you build it, and you ship it. Bloat is fairly minimal. Even if you use Qt the bloat is still a lot less than Jabba.
Good examples though. If you were building them from scratch, I would still question the choice of C++ for these as opposed to C#, Objective-C native UI layers combined with a C core.
I'll grant you a few very small niches still exist and they are in the desktop domain
Show me a popular desktop app written in something other than C++. Even when developers have tried to write a desktop app in something other than C++ (like Evernote on Windows) it was deemed a failure and was re-implemented in C++.
And you still haven't presented a compelling argument for choosing C over C++. C++ IS C, but with extra stuff that makes it better, like generics, custom types, alternatives to C's nuclear-powered casting, strings that don't blow up in your face, etc, etc. Why should a core library only be written in C?
Eclipse is the only one that comes to mind.
I'm not sure the state of consumer Windows apps but almost all desktop business apps are in C# or VB. Unless of course they are accessing legacy C++ stuff.
I can give you a few more: Chrome (not entirely new, but still the newest major browser around), Sublime Text (compare its performance with Atom to realize the strengths of C++), GoldenDict, Scan Tailor.
Actually, I've tried thinking of new Desktop apps which came out in the last 5 years and there weren't many. Developing new desktop apps is just not as popular as it used to be 10 years ago. It has a lot to do with the rising prominence of web and mobile apps, but this also has something to do with C++, when I think about it.
Writing a cross-platform web app with acceptable performance is easier than writing a desktop app with the same properties, since you'd almost certainly need to use C++ to get an app with the same properties on the desktop.
With web apps you essentially get cross-platform for free (at least since the days of jQuery and IE shims) and the performance is not stellar, but at least it's not worse than all the other web apps, so it matches your users expectations.
On the desktop, you usually get three routes: 1. C++ app with a cross platform GUI toolkit (probably Qt, since GTK user experience is usually horrible on anything other than *NIX) or an abstraction layer like wxWidgets. 2. Cross-platform Java or Mono/.NET app with cross platform GUI toolkit. There are occasional exceptions, but these apps generally tend to be bloated or hard to install, and never match the snappiness of native apps. 3. Write a separate native front-end for each platform, using its own native GUI toolkit. This usually means C with @WinForms/WPF for Windows and Objective-C with Cocoa for Mac. If you have a shared backend, you would usually still be forced to use C or C++ to make it usable with both runtimes.
C++ is only used for the COM interfaces used to talk to the measurement devices.
Evernote's case if I remember correctly was mainly caused by them using .NET 3.5 without much knowledge of the eco-system.
WPF in .NET 4.5 is not the same as the Evernote guys used.
I do like C++, but I rather use the safety and tooling of other languages.
Only C++ Builder and now XAML with C++/CX can offer similar capabilities.
EDIT: improved the content.
Qt seems to be going JavaScript gluing C++ components, given that many of the new features are QML only.
Runtimes like Java that want to install the runtime as a separate package on the system which must be separately approved and separately maintained. This also results in loads of different versions of the same runtime installed on the same machine.
As an alternative, the app author may sometimes bundle the runtime. Result: package bloat.
As another alternative, the app author may statically link the runtime. Result: binary bloat.
So your choice is between included bloat and secondary install bloat, not to mention version management nightmares and conflicts and other horrors.
Java's deployment issues are what killed it as a platform for shipping desktop apps. I tried to ship a desktop app with Java once, and never will again. C# is a bit better as it's generally installed on all Windows machines, but is MS only so is not portable.
C++ = portable, not horribly bloated, deployable, update-able, and mature.
There aren't any alternatives. This is not really a technical problem... it's just that nobody has gotten their act together to ship something that addresses these concerns. A lot of programmers don't seem to understand installability and ship things that demand follow-on package dependencies and other bloat. General rule: every installation step or sub-package exponentially increases the difficulty of deployment and maintenance.
Another problem is that these languages try to do too much. They try to be languages and runtimes, which in practice means they're OSes-within-the-OS. That means bloat is pretty unavoidable. A JVM is functionally not far from a VM running in a hypervisor, so you might as well just ship apps with Vagrant or something.
C++14 (the latest standard) is a far better language than C++ in the '90s, and it really does beat C when it comes to abstraction capabilities, type safety, and standard library functionality. C++11 also defined a standardized memory model which is extremely useful for writing multithreaded code.
Yes, C++ is not perfect -- the C++ standard library lacks a lot of functionality found in the libraries of other languages; there is a lot of complexity in the language that one must master to really "know" C++; the language itself has dark corners and disappointments; and so on. No language is perfect, and every language permits bad code.
I've been working with C++ full-time for the past three years. I didn't know much about the language before then (I was a "C 43var!" guy), but had heard all the horror stories about it. Now, I'm convinced that it's probably the best general purpose programming language available to date. It combines the full power of the machine with very expressive abstraction capabilities. Having seen what can be done with C++, I decided to study harder and try to master it.
I think this last point is ultimately what puts people off, and leads to a lot of FUD about C++ -- it takes hard work to master the language and the tools to work with it. Nobody really wants to do that, not when there are seemingly viable, and easier, alternatives. Instead, people are more willing to invest huge amounts of effort and money to try to scale up those alternatives if it means they can avoid the complexity of a language like C++. That's fine, I guess, we all have to make the appropriate engineering trade-offs, it's just unfortunate that many people fall into extremism about it in order to justify their attempt to simplify the reality of computing (which is actually considerably complex).
This is a bizarre claim. C++ has its problems, but the fact that it allows zero-overhead abstractions over common low-level boilerplate is a seriously non-trivial advantage over C in most areas where C is otherwise a good fit. What compelling advantage does C retain over C++? Faster compiles and being easier to learn are nice and all, but hardly slam-dunks.
Thanks for sharing...
However, building a not-so-bad prototype in Ruby/Python/... is much easier. So probably something needs to be done (e.g. "frameworks", libraries, tutorials) for C++.
[EDIT] C++ (templates) can provide abstractions with zero run-time cost. C doesn't have such abstractions. Ruby/Python/... don't have such low cost.
However, this could be a chicken and egg problem. People use Java more often so they produce more resources.
Just look at MFC vs OWL vs VCL, or Visual C++ vs C++ Builder.
The C++ crowd keeps trying to paper over the Mess Inside with templates, but the mold keeps coming through the wallpaper. After dealing with C++ since the mid-1990s, it's time to move on.
There have been good alternatives over the years, but their backing companies failed for other reasons. Xerox had Mesa and Cedar. DEC had Modula 3. Borland had Delphi. None went mainstream outside their niches.
Today, a compiler almost has negative commercial value. It took $20 million to launch Java, and the compiler was given away. The Go and Rust compilers are free. There was a time when a C or C++ compiler cost several hundred dollars. Now, you have to give them away. It's hard to fund development in that environment.
So without a strong revenue, it is almost impossible to provide alternatives, hence the status quo doesn't change.
http://www.steveklabnik.com/fosdem2015/
You would hardly hear about it if development wasn't sponsored.
He makes a point about Golang being a great alternative to C++ for web apps. I can't imagine that anyone is actually using C++ for web apps (are they?!?), so I don't see Golang as a C++ alternative so much as I see it as a Java or Ruby alternative. But I guess you could say that Golang is still quite literally a better choice for a webapp than C++ is - for that matter Golang is superior to INTERCAL for webapps too.
Then there's this whole coda to his post where I guess he's trying to make the point that you can't make money selling C++ compilers anymore? Is he just missing the point? C++ compilers are part of an ecosystem - of course you don't make money selling them. Why has Microsoft always nearly given away Visual Studio? Why is Xcode free? Or is Animats making a more subtle argument here that I'm not parsing?
Well, Apache and IIS modules, or web access to embedded devices.
> C++ compilers are part of an ecosystem - of course you don't make money selling them.
It wasn't always like that. Back in the 80's and 90's if you wanted a compiler for any language, including C++, buying was the only option.
I did buy a few of them.
Microsof only offers Visual Studio since the 2005 version, as open source started to make a dent into Windows.
The .NET SDK was the first developer tooling that Microsoft offered for free.
Given the price difference between Macs and PCs, XCode isn't quite free. And you need to pay 100 euros/dolars yearly if you want access to the developer program.
And if you look into the games consoles, embedded market or high performance computing, compilers are still commercial.
But in the desktop and server market, hardly anyone will be willing to pay for compilers in 2015.
Google is. They need the speed. Why do you think Google is paying for the development of Go? They need a better language for their back-end processing. 2x slower means twice as many acres of data center. C++ is too slow to write and too hard to debug, and Python is too slow to execute. (Google had a project to speed up Python, called Unladen Swallow, but it failed.)
But you're right: compilers almost have negative commercial value. So many deep pockets are spending so much and giving away the results, making it hard to compete.
C++ got into this position due to people like me, that were considered hipster back then, by going with that slow molass, full of portability issues trying to implement parts of C++ARM, instead of C.
I did it, because sadly the vendors of the alternatives mentioned by Animats didn't managed to keep their languages up to what the OS vendors were putting on their SDKs.
So stuck between C and C++, at least C++ was already a better alternative than writing plain unsafe C code.
It took several go-rounds to make Python exceptions generally useful. Originally, exceptions were just strings. Exceptions became more useful when an standard hierarchy of exceptions was defined and libraries were modified to use it. The Python exception hierarchy has a root of Exception, and one of its subclasses is EnvironmentError. Errors that reflect problems external to the program, such as I/O, network, and external data format errors, are subclasses of EnvironmentError. So if you catch EnvironmentError and report it properly, that covers most common cases. Exceptions not under EnvironmentError generally indicate program bugs, so those are usually allowed to propagate upward to the point where crash-level errors are handled. The default is a program abort and a stack backtrace.
The other problem is getting things closed out properly after an exception. C++ tried doing this by having destructors close things. This works until something goes wrong in a destructor. Exceptions raised within destructors tend to cause problems. This tends to result in ignoring errors at close time. Go's "defer" has the same problem. Calling destructors from a garbage collector is even worse. Microsoft tried to address this in Microsoft Managed C++, resulting in painfully complicated destructor semantics. (Look up "re-animation" for Managed C++, if you like.)
The Python solution was a "with" clause. This is borrowed from Common LISP's "(with-open-file ..) construct. The Python syntax is "with opening expression as object handle :". The opened object is open for the scope of the with clause, and upon exit from the with clause, the "__exit__" method of the object will be called, no matter how the with clause is executed. To make this work, I/O, locks, and database connectors had to be retrofitted with "__exit__" methods. This was done around Python 2.5-2.6; it took a while.
The result is that Python functions that open and close things tend to have this pattern:
This is reasonably simple, and tends to result in programs that do something reasonable for error conditions. Importantly, even if an exception is raised, the close operations take place. Even the case of a close operation raising an exception is properly handled; the other close operations still take place, but they are aware there's an exception situation. A database connector would do a ROLLBACK instead of a COMMIT in such a situation.This is probably the direction Rust should have taken. Error handling in Rust requires excessive boilerplate code every place an error can occur. The new Rust error hierarchy scheme [1] is especially verbose.
[1] http://lucumr.pocoo.org/2014/10/16/on-error-handling/
The problems with exceptions are well-documented (they require the programmer to write all his or her code transactionally, leading to so-called exception safety issues). Subclassing doesn't address the major issues of error handling at all, as far as I know, but again--I'd be interested to hear how you feel they are different (Rust already has an IOError that suffices for the cases you seem to be concerned about, but in practice there are many more types of error than that).
I'm frankly not sure why you think this is boilerplate, though: what, indeed, is wrong with this picture? Maybe I'm simply missing the obvious, but this doesn't even seem like that much code to me, especially given that each of your error types would have to be classes in other languages. (BTW, you don't need to prefix all the errors with Feed because they are already namespaced). Once you've written the above, you can simply try! everywhere and get automatic conversions--and you use try! a lot more often than you define new result types.
Your example also looks very much like what I would write in a language like Java, where exceptions are actually part of the signature (which is the approach Rust takes). Perhaps you are talking to the wrong person here, but I have never had an issue with Java's approach to checked exceptions, only the many ways the language provides to undermine them and the difficulty of creating new error types without ADTs.
In any case, you still haven't addressed my remaining questions re: exceptions. We may disagree on whether the above is boilerplate, but given that exceptions have other problems they are still not a drop-in replacement. I think if you consider boilerplate to be the biggest issue in error handling, you and I likely fundamentally disagree.
Now, Rust macros? Those are gross. The module system is love-it-or-hate-it. The syntax could be most charitably described as "classical" and the compiler itself is held together with reams of duct tape. But it's the first language that's attempting to explore this design space in an industrial setting and encounter all the problems therein (for god's sake, they had to reinvent the notion of closures (and even if you superficially believe they're similar to C++11 closures, the mechanisms required to make C++-style closures memory-safe are novel AFAICT)). Despite all of its flaws (and the upcoming 1.0-stable release will have flaws), it's a remarkably worthwhile language to learn and will influence every language to come that cares to call itself a systems programming language, all because the core ownership system has been so long iterated-upon (and even that will continue to see ergonomic improvements as time goes on).
c++ isn't going to be growing because it's less applicable to the new use cases but I don't think that makes it less applicable to standard use cases.
But I recently started KDevelop IDE and was very surprised how nice is C++ with QT lib. I am even considering to join an C++ opensource project.
[1] http://qt-project.org/wiki/Category:Tools::QtCreator
All the major mobile platforms support C++. Android through the use of the NDK. Windows phone has support C++ since version 8. iOS has supported C++ as long as there has been the app store, either through Objective-C++ or C++ libraries with a C interface.
But I was horrified at how bad the tools and emulator are. I spent more time trying to get things to work rather than porting code.
In other forums he has praised Qt and uses it.
Its pretty bizarre to compare it to python or ruby or perl. Yes, you should use other languages if you can. C++ is used when you cant.