"There appear to be a lot of good rants against C++....Are there any good passionate pro C++ versus C arguments?"
By definition, the people who write the "entertaining" rants against C++ have an axe to grind. The people who like C++ just silently use it, and feel no need to write advocacy blog posts for the language. Even if they were to blog about it, it would be about as compelling as someone advocating for their favorite brand of screwdriver. Like it or not, C++ is the incumbent, and it's neither interesting nor fun to read someone advocating for the status quo.
Whenever you find yourself arriving at an opinion about a programming language solely from rants that you read on some dude's blog, please keep in mind that you're probably being most heavily influenced by the very people least qualified to teach you anything useful about the language. The internet is filled with useful articles about C++, but you don't remember those. You remember that Zed Shaw couldn't figure out how const works in C++, and once wrote a funny email about it.
Indeed. At my last job, working on trading software, we had around 35 maths or physics PhDs working on a C++ application. A few had personal blogs (cats, children, steam engines, etc) but as far as I am aware no-one there argued on the Internet about which language was best. C++ just doesn't attract self-publicists the way Ruby seems to.
> C++ just doesn't attract self-publicists the way Ruby seems to.
That's a cheap shot ... Linus Tolvards is definitely not the Ruby-type.
And his arguments are sound ... for system programming, C is a much better language because it's simpler, lacks magic, making the pieces of code easier to understand without the bigger context, and it's more portable.
And for application-level programming, why would you chose a language without a garbage-collector?
Perhaps you need to run deterministically without a stop-the-world garbage collector? A) the world is bigger than simple web applications and B) some of us have been doing this for a long time.
I wasn't talking about web applications, and modern garbage collectors are not stop-the-world.
Not to mention ... stop-the-world garbage collectors have a good reason for doing what they do. They are defragmenting the memory. You get that for free, when in C++ you would have to deal with hell if your app is doing lots of allocations ... see the shit the Firefox devs had to go through to alleviate the problems of heap fragmentation, and its still a problem.
Ah, but what, you're using both managed code (C#) and unmanaged code (C++) in the same address space, doing memory intensive work using third party proprietary C++ code that does lots of small allocations?
In 32-bit land, it's welcome to OutOfMemoryException because managed code can't allocate a big enough chunk when returning to C#.
No free lunch :)
Either recycle processes often or reserve big enough contiguous chunks in managed code before calling out to the bad C++ code, no amount of good citizenship in managed code will stop the poorly written native code from fragmenting the hell out of your address space.
I've experienced problems with java's concurrent mark and sweep collector. It will stop the world, two times, but two much shorter times than a non-concurrent mark and sweep. So it is definitely an improvement in the duration of the stop-the-world.
The problem tends to be that you need to tune it, and even as you have tuned it, you can not promise that under special condition it will fall back to a more primitive collector since the optimality it was tuned for doesn't hold anymore.
I would never argue giving up garbage collection entirely because of these failure scenarios. I would much rather look at moving some critical part of the code out to a language with manual allocation, and let it perform the latency-sensitive bits.
Another mid-ground is to have separate isolate processes (heaps really) that can be stop-the-world collected without blocking each other. Erlang makes great use of this to accomplish "soft realtime", among other things.
Side rant: it's part of the reason that my Palm Pre will sometimes just hang for a second at the worst times, such as when I go to answer the phone. :(
A simple mark & sweep or stop & copy GC. Collectors which are incremental (work in small steps, not one full pass at a time) and/or generational (using several smaller generations, which are collected individually) break up GC pauses into something less disruptive.
For a good overview, read "Uniprocessor Garbage Collection Techniques" by Paul Wilson (check google scholar). Richard Jones's _Garbage Collection: Algorithms for Automatic Dynamic Memory Management_ is more in depth.
Not necessarily allocating very large chunks in bulk but umm... Allocating nodes for a million nodes of a graph and subsequently processing them. Java JVM fragments memory heavily.
En
> And for application-level programming, why would you chose a language without a garbage-collector?
Because your code uses some finite resources other than memory, and you don't want the ability to forget to release said resources when you're done with them and they go out of scope.
Why should memory management related to managing other resources. Anyway, you might be interested in The Haskell Disciplined Disciple Compiler (http://www.haskell.org/haskellwiki/DDC) which lets you statically encode resource management rules. (And of course spots garbage collection for memory.)
Your objects contain/use various resources, such as memory, file descriptors, mutexes, etc. The way to reclaim any of these is to destroy the object, which lets you reclaim all of them. So memory management is very much tied to other resource management, since they both involve the same thing (deciding when to destroy objects you no longer need). Unfortunately not all resources can be collected equally lazily, so memory-centric GC schemes that ignore the requirements of other resources tend to get in the way (and make you do using(){...} or try/finally to make sure your files are closed, instead of allowing for RAII).
How to unmix: Just e.g. close your files explicitly, but let the memory of the data structures that represent your files be garbage collected normally.
For patterns of usage similar to RAII, Common Lisp uses unwind-protect. I already mentioned Disciplined Disciple Compiler that extends Haskell to give static guarantees for following certain rules for resource management.
Why would you bother: RAII only covers some cases for resource management, and most garbage collectors can take an arbitrary long time to collect an object that's no longer reachable. Which is fine for memory, because memory is fungible, but the attached resources, say mutexen, are not necessarily fungible.
For some concrete examples of the above: WebKit, Chromium, Gecko, and V8 are all C++.
My impression is that there is a very high startup cost with C++ to getting it working on the platforms you want to support and picking the subset that isn't going to screw you. Once you get over the hurdle, the improved memory management (I agree with the post Zed is ranting in response to) starts to pay dividends.
V8 is ringing endorsement for V8. It is just a well-designed JavaScript virtual machine. It's performant because it compiles JavaScript to native code and uses generational garbase collection.
Good advice generally, but what axes do Zed and Linus have to grind? Sounds like both just think C++ enables too much complexity to be worth the benefits.
It's actually possible to make C++ nice, the Grace library is wonderful. If I ever have to C++ again I'm totally grabbing it and using it. The Grace value types and type safe format operations are just the best thing ever.
My problem though is it's not the right tool for the job. Simply having access to C level APIs doesn't instantly mean your language is awesome at making servers and operating systems. Especially if that same language can't quite figure out what the hell really happens on a copy, or during an exception, or can't make decent strings and data buffers.
I figure they have the axe of "I used this for a while, and really grew to hate it when I compared it to these other things I used" to grind. Sometimes the technologies you use just make you want to get something off your chest, you know?
"You'll find crap in C++ like const *const char &, and hell if anyone knows what that really means since even though the pointer to a const to a const reference is consted to hell and back, oh look you can still increment it."
I'm still looking for the part where he doesn't understand how const _works_.
"const *const char &" is not valid C++ syntax, so I'm pretty sure you can't increment it. Therefore, anyone saying you can increment it doesn't understand it. QED.
Oh, you have to read that in the voice of The Comic Book Guy. Then it's fucking hilarious. Here try it:
"You sthee const const &const char[const ] is the proper way to make a thruly safe reference to a conthst char array conthst pointer conthst."
See, prime comedy gold there.
Also, 'cause you guys think the internet should be nothing but a massive academic white paper curated by Knuth, so any amount of hyperbole sends you into a literalism hissy fit.
He mocks that you can attach const nearly anywhere in c++ and it seems to do something different. (Note: This is a generalization, an important aspect of many jokes)
The best pro C++ argument is that for all its flaws there's nothing out there that completely replaces it and it's still widely used.
My own view: I'm not in love with C++, but it's not nearly as bad as everyone makes it out to be. Most of the arguments I hear against C++ are the same tired things I've heard hundreds of times. They all have a grain of truth, but nothing so bad as to condemn the language.
C++ is as bad as they say it is. It is horrible, it is the worst language in the world ... except for all the other (a la Winston Churchill and democracy).
The horrifical complexifications of C++ are just terrible, yet every one of them has a reason behind it. And also, the horrifical complexities are a bit more optional than the horrifical complexities of, say, Java.
There isn't another language that has both the large-scale modularization given by OO and low-level efficiency of direct pointer manipulation and other C features. You get a vast library of available free code and a huge number of available tools to boot.
There is no other language for crafting large-scale, high performance tools. Java and C# can be just as fast but even fast Java has even greater verbosity overhead. And the scripting languages are great yet their resource overhead makes up for their compactness.
C++ is definitely a language of "big design". "Thinking in C++" is a mistake. You should think in your design and implement in C++. Unlike C, C++ seduces people to take the code for the design.
In any case, however flawed, the thing occupies a niche no other language can. I'm sorry.
Well, we can agree to disagree here, but my belief is that OO is a impedence mismatch for writing "low-level efficiency of direct pointer manipulation and other C features". It's kind of like saying, "There is no 16 wheel semi truck that can win the Tour De France." Maybe you shouldn't be using a 16 wheel truck.
If you cut a couple wheels off of an 18-wheeler, you could travel the 3642 km of the Tour de France in about 36 hours of driving, which would be about 3 days on a leisurely, safe schedule. The bicyclists take 22 days to do the same thing.
So, there are really only a couple of problems:
• if you're Zed Shaw, you apparently want to cut two wheels off an 18-wheeler, and if you're Zed Shaw, you're likely to screw up and choose the drive wheels for your demented sacrifice. You do that, the sucker won't even roll.
• the stupid hatas who judge the race won't acknowledge your achievement. Something about the allowed types of bicycle. Is that analogous to how you can't run Ruby on a microcontroller with 1024 bytes of RAM, maybe? Because you can sure as fuck run C++ on it.
Anyway, direct pointer manipulation has been part of OO environments since the beginning. The purest current incarnation might be SqueakNOS (ever seen an IDE driver written in Smalltalk?) or SBCL's alien, but the most practical one is probably C++. Rust, Golang, and ATS seem like up-and-coming contenders.
Edit: oh, I forgot D. D's been an up-and-coming contender for more than ten years now.
If we're both posting, we agree that we disagree... (along with agreeing that Paris is the capital of France..)
Anyway, C++ is more like a construction system which can be used to make a bicycle, a semi, or a six-person tandem which could win the Tour De France.
Which is to say it's pretty clunky for a lot of things. But there are still things where both large scale organization and particular low-calls need to coexist - Databases, large graphics programs, etc. It's not impossible to write these in C or Java obviously but I'd still say C++ is cleaner.
> The horrifical complexifications of C++ are just terrible, yet every one of them has a reason behind it.
Many of the reasons are legacy issues though like using dumb linkers and using the C preprocessor rather than a real module system. Templates are just a huge hack: manipulating the text of the source code to simulate generics and then abusing that feature to get meta programming.
One of the great mysteries of life is why there isn't another language that "has both the large-scale modularization given by OO and low-level efficiency of direct pointer manipulation and other C features" yet doesn't make the same mistakes as C++.
"There isn't another language that has both the large-scale modularization given by OO and low-level efficiency of direct pointer manipulation and other C features."
Arguably this might be true, however if you add another requirement to the list Joe posted it isn't. Cross platform code is important to many people. I work on large scale, performance intensive, cross platform applications. Microsoft tells me I should be doing everything in C#. Apple tells me I should be doing everything in Objective C. I just get on with it and use something that works. A language that gives me the ability to combine high level design with low level efficiency and run on multiple platforms.
I often use a paraphrase of the Winston Churchill quote as well. There are probably many better languages for many other applications, however for high performance, cross platform large scale apps C++ is still the only game in town.
Joe's point that all the complexities have reasons behind them is a really good one. I'd suggest reading Stroustrup's "The Design and Evolution of C++" for more information.
Ironically, the whole iphone apps goldrush seems to have contributed in a big way to increase its mindshare. Obj-C is very beautifully designed, I especially like how it adds message passing OOP to C with very minimal syntax additions. But then calling objc_msgSend for every message send, does have a small performance penalty attached, which mostly static languages like C++ don't have to pay.
vtables in C++ aren't free, but C++ has a couple of advantages here:
• If you're calling a nonvirtual method, you don't have to pay the vtable cost at all, just the cost of passing this. And most methods in C++ are nonvirtual.
• A call through a vtable is typically a couple of indexed fetches and an indirect jump. Objective-C's mechanism involves a hash-table lookup, which is a bit slower.
There is no other language for crafting large-scale, high performance tools is demonstrably false. There are high-volume low latency world-class financial systems written totally in Java.
The seriously complex and high-performance ITA system is written in Lisp.
And if you read Coders at Work, some of the criticisms of C++ suggest that the reason behind many of the C++ features is that Bjarne didn't want to say NO.
And I am happy to leave that particular niche of badness to C++ its own self.
I guess, if you set your mind to it, you could probably make Forth do a nice mixture of low and high-level stuff, too.
But why do people insist on being able to do low and high level stuff in the same language? What's wrong with, say, using Python for high level stuff, and calling into C for low level tasks? C+Python is probably more convenient than C++.
Actually Boost::Python makes python and c++ mix beautifully. I just started playing with it a few days ago and am seriously impressed. I'm planning on using it to write a WSGI gateway to put in front of my bottle.py apps.
I should have said "there is no other language which gives you the latitude for crafting high performance tools". You can indeed create serious high performance systems in a number of languages. The thing about most languages other than C and C++ is that things written in them tend to inherit their qualities - A system written in Java generally use Java's garbage collector. That works great for a number of things but it's still a constraint.
More of C++'s "modularization" features are optional than in the other languages so you have more latitude for creating your tools than anywhere else.
The seriously complex and high-performance ITA system is written in Lisp
Have you worked on it? Do you know this? Is it all written in Lisp, or are the parts that need high-performance and predictability written in C or C++?
There's a lot of language FUD out there. I say this as someone who owns OnLisp, and has spent a lot of time learning Lisp.
Until there's a single, stable, not-on-the-way-to-be-obsoleted version of D, with standard standard library, I'm not inclined to invest too much time in it.
I wish that D1 was oficially killed, and a stable strict subset of D2 ("D1.5") was chosen as a recommended future-proof version.
What you say about Java's verbosity is sort of flawed in the same way that attacks on C++ about its template metaprogramming madness are flawed. Don't confuse a language with what people write in it.
There is a point though. C++ encourages obscure "too clever" constructs, and Java encourages excessive verbosity. But in both cases you can decide not to go there.
As far as I know, there's a lot more to Java that isn't optional: everything must be inside a class definition, everything must use the garbage collector.
In C++, you don't have to declare a single class or create a single template.
Lots and lots of things are bad in C++. But that's because it's an elaborate language with lots of things in it. You only have to use one bad thing at a time ;-).
Basically, any language with lots of modularity and lots of low level access is going to be big and have lots of features that are problematic in some situations.
Say you need both modularity and low level access in a given program. Can they be so entangled that you absolutely have to put both in the same language?
No matter how I put it, I fail to see how C++ can be better than C + (Python or Lua or Haskell, with FFI). Is the concept of using 2 languages at the same time so scary?
"Say you need both modularity and low level access in a given program.
Can they be so entangled that you absolutely have to put both in the
same language?"
That's not always an option if you've performance and memory constrains.
We're using Python only for high level scripting purposes.
If you've a performance critical function, where few data goes in,
long computation and few data out, then it's perfect to implement
this function in C and have a python function calling it.
But if you've a lot of data, then that's not an option. You just can't
copy all the data to C and then after computation back to python,
it will kill the performance gained by the C function implementation.
But also if you're trying to do complex operations on your application
object hierarchy, Python will kill your performance. Only compare
the time for a member/property access in Python and C++.
Is the concept of using 2 languages at the same time so scary?
In all honesty, yes.
But consider this also. The advantage of C++, such as it is, is that the big, harry objects you are creating can call each with just about any calling conventions you chose and you can parameterize them at run time and compile time in whatever crazy way you'd like (pointers, templates, static objects, classes and ponies! (Ponies will only be standardized in C++_2015)). This is why Python, Lua and all each call c/c++ for extensions. But while there are many interesting scripting languages out there, there's no guarantee that any of these languages' calling convention, memory usage and constraints will be what your large objects need. Specifically, to effectively use a particular higher-level language you'd have to know from the beginning that said language's conventions would satisfy your needs from beginning to end.
Add to this the fact that C++ may not be a "good" programming language but that it's not that bad if used with discipline and understanding. The badness of c++ comes from the many, many ways you can shoot yourself in the foot - it still doesn't force to do anything. But how many subtle bugs can creep in if you're sloppy in passing raw pointers to some other language? And using any higher level language will involve forcing yourself to do a number of things that could prove problematic.
| Is the concept of using 2 languages at the same time so
| scary?
Yes, but it seems to be inevitable. Python + C. Haskell + C would be my choices for large scale modeling/data analysis. For apps involving a GUI, I would like to hear others thoughts.
Basically, any language with lots of modularity and lots of low level access is going to be big and have lots of features that are problematic in some situations.
It has grabbed and maintained complete domination of nearly all performance sensitive code in games and desktop software, for nearly a generation now which is an unprecedented reign in computing history. That's a pretty good start to me.
I don't know if he's saying that, but yes, nearly all performance-sensitive code in games and desktop software is written in C++, not C. Objective-C seems to be edging in.
* Linus Torvalds : http://lwn.net/Articles/249460/
* C++ Frequently Questioned Answers : http://yosefk.com/c++fqa/
Are there any good passionate pro C++ versus C arguments?