I'm about to start a gig with a team who want to go Extreme, and who are using CeePlusPlus. For ages here folks have been talking about how you can't write adaptively in C++ because of the huge build times, etc etc. That wasn't quite my experience when I used it, but maybe my projects were small.
So, my wise and experienced colleagues, advise me on some or all of these questions, and add and answer more of your own:
Because I wouldn't recommend Smalltalk to anyone these days. Much as I like it, I think it's moribund, if not just mori.
We can bounce this around in all kinds of ways
-- JezHiggins
I've used C++, and for reasons that won't surprise anyone, I found that the advantages of objects just about balanced off the loss of flexibility. Compile/link times discouraged rework, which is central to XP tenets.
I know that AlistairCockburn rates C++ as one of the prime danger signs on the many projects he has studied. My observations lead me to the same general conclusion: people go C++ and never come back up.
I expect that at this new gig I'll find that C++ isn't helping them, and that I'll try to encourage them to do some other things instead, or to carve off parts for Java, or [I don't know yet].
So my questions are to try to get the lay of the land, pretty much just as stated:
Why, really, do people do this? Are there good reasons to stick with C++ in spite of its obvious disadvantages? If people who had used it to write X were given a chance to write X from scratch, would they use C++ again, and why? What would they use instead? Does C++ survive for good reasons, what are they, etc ...
And what are viable alternatives, either going to new languages, or to maximize flexibility within C++?
Why, given the many alternatives, does C++ continue to be so highly used?
Inquiring minds want to know. -- RonJeffries
RichardGabriel wrote a good account of the cultural forces in his essay "The end of history and the last programming language" in his PatternsOfSoftware book.
'Why, given the many alternatives, does C++ continue to be so highly used?' Fear. The only reason I see is Fear. Misguided, I think, but fear nonetheless. At my company, we use CommonLisp, with great success. I posit that we would have been successful with just about any useful/applicable technology (e.g. Python) - it just happens C++ isn't it. But unlike other places I've worked, we were not afraid to move to something better. -- AlainPicard
Java as an alternative to C++
However, I can suggest Java as an alternative to C++. It's simpler for C++ programmers to adapt than Smalltalk, and it still has a lot of the good parts of Smalltalk (especially when you use VisualAgeJava, which gives you something very much like a Workspace for trying out bits of code and the ability to change code in the debugger).
If it's really an IS application, then Java should be an acceptable alternative, considering that so many useful libraries for Java are out there now, and that it's so well supported by compilers and tools. -- KyleBrown
Java is an improvement, and it is also the most superficially similar language. I haven't yet run into a C++ programmer who didn't appreciate Java's perks. For transitioning's sake, you can call C++ from Java and vice versa. I'd just find a chunk of the system with a narrow interface and work with it.
If you stay in C++, there are all sorts of tricks that you can use to maintain flexibility, but many of them are geared more towards flexibility under pressure: "how do I allow myself to make a change without having to recompile the whole system?" Many of the tricks are documented in JohnLakos' LargeScaleCppSoftwareDesign book. Much of it can be summed up as "keep stuff out of header files." From an XP point of view, I'd take it slow and transition into stability. As classes become more stable in a package, start thinning out the headers to get compilation speed improvements. With tests, you can get pretty mechanical about packing and unpacking classes for change episodes.
Regardless of what you do, compilation becomes painful for a large project, but pain is relative. I've seen a 2000+ class system that takes about 2 hours to compile and a 400 class system that takes more than half that. The former system's developers were more aggressive in keeping dependency down. The Lakos techniques help; good factoring helps also.
I've noticed that the discipline of developing classes in separate test harness executables, by itself, goes a long way towards keeping the physical coupling down. You are immediately conscious of what you have to include and what you have to link to get the new class working, and you can work to improve things.
Coding and design conventions are very important because of the fact that C++ gives you endless tradeoffs. A team should have a set of "forms" and policies that they use. A consistent policy towards memory management is essential.
I'm a veteran of several large projects written in Java. Microsoft Liquid Motion was around 220 kloc of Java, although it was by no means pure since we made gazillions of native API calls. It was certainly no speed demon, but then again, it was a multimedia product, and not your run-of-the-mill IS app. The biggest performance problems I ran into that weren't caused by external components were memory allocations for temporary objects. These were easily optimized using a simple pool allocation scheme. We also had a problem with slow startup just because loading the JVM the first time was such a big hit, and we took a big overall performance hit on low end (32M) machines because we had a horrendous memory footprint. However, I can't imagine that any of these issues would be serious for an IS app, few of which I would expect to be as big and memory intensive as LM.
I think it's the other questions you need to worry about. For example, what Java platforms do you need to run on? Do you need to run inside the browser? Can you live in the Java sandbox? Do you need to call native APIs? Do you want to use the latest Java 2.0 features?
People use it because it occupies the intersection of OO and C. That is sufficient all on it's own. Because it lets people pretend they'll get speed ("close to the metal", "pay as you go"). By the time they learn the truth, it's too late (unless their middle initials form an anagram of JimCoplien).
What about Java performance? I offer the following: Java is a mix of Smalltalk and C++. You get some good from both, and some bad from both (depending on what you like). The good is garbage collection (if you like that). The bad is compile-time type checking (if you don't like that). The bad is in all cases performance, but, shoot, that's old hat to a Smalltalk programmer ;-). Same rules apply:
I find that the performance of C code called via JNI (JavaNativeInterface) is indistinguishable from C code called in a C program. You can fairly easily demonstrate this yourself, I'm sure. At that point, the objection is only reasonable if the system being coded is all performance bottleneck, with no hotspots at all.
Well, it did in the application I most recently worked on. It's an automated bond trader. You have to update thousands of entities, several times a second (every time a futures contract moves). Most time is spent in the analytics, which had to be as fast as possible. If you are too slow updating, you will be automatically arbitraged by other machines, which is a painfully expensive process.
I coded the analytics both in pure Java and in C++ called via the JNI, to compare timings. JNI overhead is less than a millionth of a second per call if you use GetPrimitiveArrayCritical?(). On Intel x86 machines, C++ can compile to a processor instruction for some functions (e.g. exp()) that Java emulates in software due to the language-specified precision that the functions have to meet. For this particular project, the C++ speed outweighed the JNI overhead, so the C++ via JNI option was faster.
I like C++. I've been trying XP in C++ for the last year and I think it's great. It does make you realise how important fast edit/compiler/test cycles are. I wish the C++ tools I use (mostly Visual Studio and C++ Builder) were faster, but if you pay attention to (recursive) dependencies of your header files, it is not really a problem, although it is still irritating. But it's mostly a tools problem, not a language problem. If you stored your source code in a more convenient format instead of the horribly outdated text files we use today, recompilation could be much faster. If you interpreted the code, the cycle would be even shorter. I see no reason why you couldn't build a Smalltalk-like IDE for C++. That's something I'd like to do someday. -- MartijnMeijering
Indeed there was once an environment just like this. Lucid were the company who produced it as I recall. Incremental compilation was their game, and they really could have scooped the pool - except they priced themselves out of existence.
And it's not all about performance. I write C++ code that runs on Linux, Solaris, Irix, SunOS, Alpha OSF, and now Windows NT. Can you get a JVM for everyone of those? And if you could, would you never have to maintain separate source trees because of lack of conditional compilation? I know with Java AWT people have been forced to do that, because of platform specific user interface issues that couldn't be ignored. Swing promises to be different, but do you think those kind of problems will never crop up again in the whole canon of Sun-approved class libraries? What about incompatibilities between Java 3 and Java 2? Do you really think there will be none? Evolution of frameworks is ok, but dealing with it without conditional compilation is hard. And the ideology of Java seems to guarantee that this feature will never get added. -- ScottJohnston
See also ExtremeGuidelinesForCeePlusPlus
I think that your response contained within it the key difference in viewpoints between Java and C++. You say that you write C++ code that runs on Linux, yada yada yada... and then yet your argument is that the way in which you do this is through conditional compilation. The principle within Java is that conditional compilation is a BAD thing since you're not writing the same program for all OS's. Whether or not it lives up to its ideal is another matter, but that is the philosophy. Now, about the migration issues from Java 2 to Java 3 and so forth - your code should be upward compatible - but then again, have you recently tried to recompile an old piece of C++ code written for MFC 1.0 and tried to make it run on Windows 2000? The issues are still the same... In that case conditional compilation makes your program compile, but it looks grungier and grungier over time as it accumulates gorp. The principle behind Java is to minimize that impact, but at the same time it does force multiple code releases - which isn't necessarily a bad thing. -- KyleBrown
An alternative to using only C++ is AlternateHardAndSoftLayers: write the structure in a flexible, modular, "pure" OO language, and call down to C or C++ (or Squeak-generated C) when you really need the speed or bit-twiddling abilities.
I like Java much better than C++ myself, as I am a bear of little brain. But what's the truth of performance between the two? I feel that will be the first objection, whether or not valid. -- RonJeffries
Obviously it depends on what you want to do. I've had to re-write java code in c++ to be able to optimise it. If you are doing CPU limited stuff (i.e. not a GUI) then Java begins to show its weakness (Strictly speaking, I should say that its the VM approach that is weak: any language compiled onto the JVM would suffer the same problems).
In one case, I was analysing trace files from some simulations. The trace files were fairly small - only about 30 MBytes of data, and it was taking over an hour to parse them and then about 15 minutes to process the data. I did a simple-minded translation to C++ and got the parse time down to 2 minutes and the processing down to about 15 seconds. I then replaced the string class with char[] for parsing, and got the parse time down to 40 seconds. This was a significant reduction in time. (I was using a Sparc with 2 GBytes of physical memory - I had to set the heap size to 1.4Gig to avoid out-of-memory errors. The C++ only needs about 120 MBytes.)
Library availability: respectable libraries for image processing, machine control, industrial automation, data acquisition are mostly C/C++.
As is (on a Unix system anyway) the C library, which usually provides the only supported interface to any operating system features. For this reason even if no other, language implementations tend to provide some mechanism for calling libraries written in C. AlternateHardAndSoftLayers, baby - SimplifiedWrapperAndInterfaceGenerator may be a good place to start. -- DanBarlow
At a minimum you can use C++ as a better C, don't use any classes of your own at all, take advantage of stricter type checking and many other goodies, including templates.
Once I had to refactor something in a project where I wasn't in from the beginning. As a matter of fact I was brought there based on my experience in Oracle. It was about taking some raw external data (tons of lines of fully denormalized text files (several chunks each file), worth like 5GB of data, and loading it into an Oracle database, after checking for various integrity constraints, reformatting, and performing some transformations.
I had to do it quickly, refactor promptly after each of the many twists in the specification (they always came back with new business rules) and it had to run extremely fast, so I chose C as a better C++ and just did it.
Probably the code that I left behind me is not quite maintainable by someone who is not a seasoned C/C++ programmer (even if I left some documentation, and I verbally talked a programmer from the customer IS department into how the code is working) and this is the only downside that I find in what I did.
It was for me a window of happiness after I've been programming Java continuously for too long time.
I tend to use C++ for things that matlab is not fast/powerful enough for. Java isn't even an option in the domains I usually find myself in. If I worked really hard, asked some experts, constrained my data or machine types in the right way (java is somewhat broken for numerics), I am sure that I could get the java code to within a factor of 2 or 3 of my C++ code. So that means that the run (I hope) is finishing tomorrow would take 6 weeks instead of 3. My worst case would top the 4 month mark. In this case (and I agree that this is not the usual programmer's position) it just isn't worth considering.
I use AlternateHardAndSoftLayers where I can. For example, a python application sitting on top of a highly optimized (expression templates) N-dimensional array class. I find this combination gives me all the putative advantages of Java, with better performance and control. Granted, some of my C++ is pretty hellish looking, but it is fast. On the order of Fortran, with the scaling and other advantages of *not* using fortran.
Why do I like C++? Because it allows me to write clear code which is still efficient. In Java I have to make a choice between absolute clarity (lots of abstraction, but lots of wasted time creating objects and hence garbage) and efficiency (more use of primitives and techniques to avoid producing garbage). In C++, creating objects is cheap as they can be either on a stack or directly embedded inside other objects. Java makes this all go via pointers, as do dynamically typed languages.
C++ also has the ability to do computations at compile-time, and to produce tiny binaries. C++ is more widely available than Java. C++ comes with a more solid standard library than does Java; it's defined by an ISO Standard, and does not change every 18 months. C++ applications can be distributed without worrying about licensing for a virtual machine, or the bloat of distributing one.
Maybe this page should be called AlternativesToCeePlusPlus (with portions moved off to CeePlusPlusIsntReallyThatBadIfYouAreCareful?). There are choices other than Java out there, believe it or not:
JavaVsCpp
One truth about performance is that you cannot garbage collect faster than decrementing the stack pointer.
Ever.
Which is why smart compilers do data-flow analysis (or whatever it's called) to see what is used where.
After 13 years as a C++ programmer, I've recently settled on SmalltalkLanguage as my alternative to C++. Java is more fun than C++, but Smalltalk is a whole different way to program altogether. It can't be coincidence that ExtremeProgramming, UnitTest and ReFactoring originated in the Smalltalk community. My theory is that it's because they had the extra time.
I like RubyLanguage for OO programming. It's easy to learn and is pure OO. It's also supposed to be very easy to extend in C, so the hard and soft layers thing should be doable. (I haven't done any extensions, but I looked at the directions for doing so -- much simpler than Perl!)
Why use C++?
My background is real-time embedded. In embedded systems resources are often highly constrained. No room for a VM. Low power processors. These systems have traditionally been written in C or C++. Writing OO programs in C is hard work. OOP gives you major advantages. C++ sort of combines these two capabilities - small footprint / fast and OO. That was why I started using it. With mixed success.
In recent years embedded systems have become more capable, but as recently as last year I was working on a 20MHz processor with 4k of stack. We wrote everything in C. C++ would have been a better choice for some tasks (templates would have helped in a number of areas), but the team was struggling even with C (worst team I ever worked with) and C++ would have killed the project dead because of its complexity and the inexperience of the team.
These days I'm writing a lot in the PythonLanguage. The code I'm working on now is mostly IO bound, so raw performance is not an issue. And I have a big powerful target machine. I find Python around 3 to 5 times more productive than C or C++. That is a really good reason to use it. If I have to, I will resort to C or C++. I choose C++ if I need OO at the low level. But if I can I will write everything in Python. I often use C and provide the OO just in the Python layer.
I spent a long time evaluating and using Java. I found that its performance is poor at many tasks and its syntax is verbose. And I hate all those casts. It has advantages over C++ in garbage collection, better exception handling, thread support and a decent set of libraries. The JNI is terrible though. C++ offers none of these things off the shelf. The lack of standard portable libraries is a good reason to be wary of using C++ (The STL was just out when I did the comparison). You waste too much time reinventing wheels just to provide basic infrastructure.
I have had to worry a lot about porting code between wildly differing OSes. I've developed C on old 16-bit WinTel machines and run the same code on a 32-bit BigEndian embedded target. But you need to be very careful how you code. Java and Python hide this from you with the VM. C and C++ rely on you being careful. This takes up a lot of your time. I couldn't use a VM because I only had 1Mb of RAM and a 16MHz uP. But I would have used C++ if I had the choice. Java would not have had the performance I needed in this application.
C++ is a complex language that demands a lot from your programmers. But it offers very little in return. If you need high performance and OO then it is probably a good choice. But how much of your code needs to be high performance? Even in real-time systems the hard real-time part is typically only a few percent of the code. Python is very clean and very portable. These days I would try and bully the hardware guys into providing target hardware that will support a Python VM, and use Python and C. And possibly C++.
Choice of language depends on many things - you need to assess your constraints and environment carefully. And of course your team. And then choose Python if you can :)
-- DaveBerkeley
Why use C++?
For one, because nobody asked me. That aside, we're doing it on Linux, we need (for business reasons) tight integration with some C libraries that aren't easily wrapped, and I prefer static typing on a project this complex. Also, considering that the oh-so-very-C libraries we need change fairly regularly and wrapping them is non-trivial, what other option do we have? The particularly depressing part for me is that we use Good C++ Style, which means lots of STL and templates, which in the end means that wrapping or soft-layering into something else is not justifiable.
A real alternative to C++
All the above-mentioned languages (D, Java, Lisp, ...) are no real alternatives to C++ because they meet different requirements.
The core features that a real alternative should have are IMHO:
It would be nice to see a real alternative to C++ with simpler syntax and fewer pitfalls than C++, but I haven't seen such a language yet.
It would also be nice if this alternative had the possibility for static reflection information provided by the compiler and to differentiate between objects on the stack and within objects on the heap (with this one could implement garbage collecting mechanisms in a portable way in the language itself).
There are three mains reasons why people still use "plain C" and "C++".
One. You do can do things on those languages. Even with all its pitfalls.
Two. Fear of change. Fear of I.T. Departments, developers, & companies to try new things.
Third. the "Must have plain C syntax". That makes Oberon, Object Pascal / Delphi, Basic syntax languages, and a lot of the new functional languages, be discarted by developers.
Go, Java, (Digital Mars) D, & C#, PHP. All of them, work as "C++" replacements, in certains situations.
I think D is the most alike to be a real "jack of all trades: C++" replacement, must that is very subjective, also.
-- umlcat