Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.
If this question can be reworded to fit the rules in the help center, please edit the question.

26

So something that can be done using C, perl and python together can be done using C++ only. And you are asking why to use C++?
–
Manoj RDec 23 '10 at 5:37

18

« When I'm going to performance, the first and last choice is C. » yeah sure :D This is an unproven, and trivially wrong assertion.
–
deadalnixAug 2 '11 at 17:06

10

@deadalnix: I wouldn't say that. C++ has complex rules that might backfire on optimizer, because it's not allowed to do some things. And it's super easy to step into invisible performance killers. It's pretty much axiomatic, and therefore true :D Still in reality C++ code will sometimes be faster because you'll be using more effective algorithms and data structures, and noone actually optimizes C code anyway. So when done correctly, C++ is safer and more effective C, and you should pick C++ over C when there are no compatibility problems, or requirement for 100% availability software.
–
CoderDec 18 '11 at 21:43

1

The best reason, not considered in the posted answers, directly relates to OP's question. DEPENDANCIES!!!!, Not that your average system lacks the c++ libs, but an embedded system might not have them available. The only way to to get your program in every system, is to write your program in regular C. Everything else is just debating why you should, or less represented, should not use C++. None of that addresses why C++ is not used more often, and regardless of merit, the reason is dependencies.... O and also Linus's famous c++ rant.
–
TechZillaApr 2 '13 at 22:01

19 Answers
19

And that’s where you should back up. Now, I cannot, at all, speak for server development. Perhaps there is indeed no compelling reason to prefer C++ over the alternatives.

But generally speaking, the reason to use C++ rather than other languages is indeed performance. The reason for that is that C++ offers a means of abstraction that has, unlike all other languages that I know, no performance overhead at runtime.

This allows writing very efficient code that still has a very high abstraction level.

Consider the usual abstractions: virtual functions, function pointers, and the PIMPL idiom. All of these rely on indirection that is at runtime resolved by pointer arithmetic. In other words, it incurs a performance cost (however small that may be).

C++, on the other hand, offers an indirection mechanism that incurs no (performance) cost: templates. (This advantage is paid for with a (sometimes hugely) increased compile time.)

Consider the example of a generic sort function.

In C, the function qsort takes a function pointer that implements the logic by which elements are ordered relative to one another. Java’s Arrays.sort function comes in several variants; one of them sorts arbitrary objects and requires a Comparator object be passed to it that works much like the function pointer in C’s qsort. But there are several more overloads for the “native” Java types. And each of them has an own copy of the sort method – a horrible code duplication.

Java illustrates a general dichotomy here: either you have code duplication or you incur a runtime overhead.

In C++, the sort function works much like qsort in C, with one small but fundamental difference: the comparator that is passed into the function is a template parameter. That means that its call can be inlined. No indirection is necessary to compare two objects. In a tight loop (as is the case here) this can actually make a substantial difference.

Not surprisingly, the C++ sort function outperforms C’s sort even if the underlying algorithm is the same. This is especially noticeable when the actual comparison logic is cheap.

Now, I am not saying that C++ is a priori more efficient than C (or other languages), nor that it a priori offers a higher abstraction. What it does offer is an abstraction that is very high and incredibly cheap at the same time so that you often don’t need to choose between efficient and reusable code.

I do now know enough about C++ to know whether you are spot on or wrong. But also want to add you only received 1 downvote so relax. This is the internet and downvotes happen. Great answer though if its technically sound!
–
ChrisDec 22 '10 at 17:51

29

no performance overhead at runtime - that's not always true. If you look at STL vector implementations you will see that they don't take the advantage of using realloc() (they can't because of pointers, long story) whereas all higher-level languages that I know can and do use realloc() in vector impl's. This is just one example that it's not that obvious and all black-and-white.
–
mojubaDec 22 '10 at 20:55

16

@Jaroslaw, @Steve: but the same (= code bloat, instruction cache misses) is true for hand-optimized code which is adapted for each data type (see Java’s various Arrays.sort implementations). Only you lose the advantage of high abstraction. This isn’t a specific disadvantage of templates, it’s a disadvantage of code duplication in general. Furthermore, this tends not to matter since in tight loops, it’s usually always the same code that is loaded.
–
Konrad RudolphDec 23 '10 at 10:20

14

@Jaroslaw: the funny thing about the instruction cache is that it is a cache. That is, it does not try to store everything, only recently used code. Templates might generate lots of similar code for different types (a vector.push_back for vector<int>, and another for vector<float>, but while working with a vector<int>, there is little reason why the vector<float> code would be in the instruction cache. So I don't see how that really matters. Every individual template instantiation is highly optimized and typically more compact than generic catch-all implementations
–
jalfDec 23 '10 at 14:42

20

@Steve314: What you call "bloat" is what is done manually for C and Java. In C++, it can be automated, and compilers can be as smart as vendors dare to make them to avoid bloat. If I have to decide between either being slow (as in C) or use duplicated code (as in Java), having the compiler doing the duplication (and maybe being smart about it) seems pretty good, no?
–
sbiDec 27 '10 at 23:27

I see way too many C programmers that hate C++. It took me quite some time (years) to slowly understand what is good and what is bad about it. I think the best way to phrase it is this:

Less code, no run-time overhead, more safety.

The less code we write, the better. This quickly becomes clear in all engineers that strive for excellence. You fix a bug in one place, not many - you express an algorithm once, and re-use it in many places, etc. Greeks even have a saying, traced back to the ancient Spartans: "to say something in less words, means that you are wise about it". And the fact of the matter, is that when used correctly, C++ allows you to express yourself in far less code than C, without costing runtime speed, while being more safe (i.e. catching more errors at compile-time) than C is.

Here's a simplified example from my renderer: When interpolating pixel values across a triangle's scanline. I have to start from an X coordinate x1, and reach an X coordinate x2 (from the left to the right side of a triangle). And across each step, across each pixel I pass over, I have to interpolate values.

When I render in "Phong" shading, I no longer interpolate an intensity (ambientLight) or a color (red/green/blue) - I interpolate a normal vector (nx, ny, nz) and at each step, I have to re-calculate the lighting equation, based on the interpolated normal vector:

Now, the first instinct of C programmers would be "heck, write three functions that interpolate the values, and call them depending on the set mode".
First of all, this means that I have a type problem - what do I work with? Are my pixels PixelDataAmbient? PixelDataGouraud? PixelDataPhong? Oh, wait, the efficient C programmer says, use a union!

First of all, one typo is all that is needed to crash my code, since the compiler will never stop me in the "Gouraud" section of the function, to actually access the ".a." (ambient) values. A bug not caught by the C type system (that is, during compilation), means a bug that manifests at run-time, and will require debugging. Did you notice that I am accessing left.a.green in the calculation of "dgreen"? The compiler surely didn't tell you so.

Then, there is repetition everywhere - the for loop is there for as many times as there are rendering modes, we keep doing "right minus left divided by steps". Ugly, and error-prone. Did you notice I compare using "i" in the Gouraud loop, when I should have used "j"? The compiler is again, silent.

What about the if/else/ ladder for the modes? What if I add a new rendering mode, in three weeks? Will I remember to handle the new mode in all the "if mode==" in all my code?

Now compare the above ugliness, with this set of C++ structs and a template function:

Now look at this. We no longer make a union type-soup: we have specific types per each mode. They re-use their common stuff (the "x" field) by inheriting from a base class (CommonPixelData). And the template makes the compiler CREATE (that is, code-generate) the three different functions we would have written ourselves in C, but at the same time, being very strict about the types!

Our loop in the template cannot goof and access invalid fields - the compiler will bark if we do.

The template performs the common work (the loop, increasing by "step" in each time), and can do so in a manner that simply CAN'T cause runtime errors. The interpolation per type (AmbientPixelData, GouraudPixelData, PhongPixelData) is done with the operator+=() that we will add in the structs - which basically dictate how each type is interpolated.

And do you see what we did with WorkOnPixel<T>? We want to do different work per type? We simply call a template specialization:

That is - the function to call, is decided based on the type. At compile-time!

To rephrase it again:

we minimize the code (via the template), re-using common parts,

we don't use ugly hacks, we keep a strict type system, so that the compiler can check us at all times.

and best of all: none of what we did has ANY runtime impact. This code will run JUST as fast as the equivalent C code - in fact, if the C code was using function pointers to call the various WorkOnPixel versions, the C++ code will be FASTER than C, because the compiler will inline the type-specific WorkOnPixel template specialization call!

Less code, no run-time overhead, more safety.

Does this mean that C++ is the be-all and end-all of languages? Of course not. You still have to measure trade-offs. Ignorant people will use C++ when they should have written a Bash/Perl/Python script. Trigger-happy C++ newbies will create deep nested classes with virtual multiple inheritance before you can stop them and send them packing. They will use complex Boost meta-programming before realizing that this is not necessary. They will STILL use char*, strcmp and macros, instead of std::string and templates.

But this says nothing more than... watch who you work with. There is no language to shield you from incompetent users (no, not even Java).

Templates and the STL. You trade a little build time (and some potentially incomprehensible error messages) for a lot of useful abstraction and labor-saving tools, with no appreciable run-time performance hit (although the binary footprint may be a little larger).

It takes a while to wrap your head around (took me a couple of years before it clicked), but once you do it can make life a lot simpler.

Text processing in C++ is orders of magnitude less painful than it is in C.

Boost is the only reason I still use C++.
–
FerruccioDec 22 '10 at 23:28

25

@Nils: On a scale of 1 to pain-in-the-ass, text processing in C++ is definitely worse than in more modern languages like Python. It's just that text processing in C defines pain-in-the-ass. If the choice is between C and C++ for that particular application, then C++ wins easily.
–
John BodeDec 23 '10 at 0:15

7

I dont know why people have such difficulty with things like text processing in C/C++. Just use a library or write your own. Once you've written the low level functions (one-time pain) you gain massive performannce, tight code and greater flexibility. Yes, I'll use Python for quick/dirty command line utilities but for serious production code its C/C++.
–
user11465Dec 23 '10 at 10:06

If you're looking for executable efficiency, you're down to C or C++, so I'll focus on that.

Even before templates were common, I preferred using C++ over C for the kinds of executables you discuss as early as the mid 1990s for two very simple reasons: object polymorphism and RAII.

I've used polymorphic C++ objects for all kinds of interesting things. For instance, I was working on an embedded Linux system with frame buffer overlays on OMAP and XScale ARM CPUs. The two hardware architectures have different overlay features with very different APIs. I used a common virtual "Overlay" base class to expose an idealized view of overlays, and then wrote "OmapOverlay" and "XScaleOverlay" classes which were instantiated appropriately at runtime, depending on which architecture the code detected it was running on.

To oversimplify, RAII is the idea that you allocate resources connected to an object during the object's constructor, or maybe later on in the object's lifetime, and the resources get deallocated or released in the object's destructor. That's really nice in C++, because objects which are automatic variables are destructed when they go out of scope. For someone who's equally competent in C and C++, it's far easier to avoid resource and memory leaks in C++. You also don't see much C++ code with the very common C meme of a label at the end of a function preceding a bunch of calls to free(), and various goto's in the function block jumping there.

I'm fully aware that you can do all these things with C - it's just a lot more work, way more lines of code, and what you wind up with is a lot uglier and often harder to understand. There's polymorphism code all through the X server internals, and man, is it fugly and weird and frequently hard to trace through.

I also do a lot of work with GNOME technologies like GTK+ and Clutter, all of which are written in C using the GObject system. GObject is like the C++ object system with the nice cover taken off and all the ugly internals exposed, and it usually requires a half-dozen lines of code to do what a one-line C++ method call would do. I'm currently writing some ClutterActors, and while the math is really interesting, I'm constantly thinking, "This would all be so much more succinct and comprehensible in C++".

I also often think, "You know, if I were writing this in C++ instead of C, I'd be out in the living room watching MythBusters with my wife instead of sitting in my office at 9 PM."

I can really relate to what you're saying here, especially 1) the point about RAII and 2) the thought "You know, if I were writing this in C++ instead of C..." I do a lot of embedded systems development, and even if the team is pretty much a "C" or "C with classes" kind of shop, I really try to encourage RAII for things like interrupt manipulation, mutex operations and tracing/logging (esp. things like toggling I/O lines). And your description of polymorphic frame buffers reminded me of my use of polymorphic message buffers in a distributed system.
–
RadianDec 22 '10 at 19:11

C++ is about as fast as C (some things are faster, some slower), and it offers better abstractions and organization. Classes work similarly to primitive types, allowing large amounts of code to be used without being held in mind. Operator overloading and templates make it possible to write code that functions better if data representations change. Exceptions can allow easier error-handling. The compiler can be used to check more stuff at compile-time.

The price you pay for this is a fairly nasty learning curve, and it's easier to make subtle mistakes in it than most other languages I'm familiar with.

So, I can't tell whether it would be worthwhile for you to learn it for what you're doing now. You can certainly get by with combinations of Python or Perl and C, but C++ offers both abstraction and performance in one hard-to-get-used-to package.

Back then it was big because it offered higher-level language constructs and mechanisms at a lower cost in terms of performance. It was the universal tool for developing everything from address book applications to avionics software, and that inspired the OO craze. OOP solved hunger and AIDS, and yes, I blame C++ for trying to brainwash me in the late 1990s when I first started programming that any non-OO language isn't worth learning.

Now that hardware has advanced so much and newer, modern languages have appeared, I fail to see C++ remaining a relevant choice for most application programming except for computationally intensive software where you still need some abstraction (games, physics simulations, CAD systems, etc.). Even the latter can be avoided if you write a compact, modular engine in C and have higher-level application logic delegated to a neat scripting language.

If you need to go down to the metal use C sanely, and when you need to go high-level, do it in a modern language that doesn't advertise encapsulation while you can freely alter each byte through a pointer.

So don't alter random bytes using pointers. That's not so difficult to avoid, isn't it?
–
David ThornleyDec 22 '10 at 18:24

8

@Blagovest: I agree with you about C++’ complexity and I would never use it to replace an object-oriented language. But despite its complexity it still wins over C for me because of its many advantages spelt out in different answers (abstraction, resource handing, string handling …). In fact, you have named a few valid areas where C++ is still relevant, and where it’s far superior to C.
–
Konrad RudolphDec 22 '10 at 20:16

5

@Blagovest: That's why I stay out of the dark corners. It's easier to get mugged there in C++ than any other language I know. By using it, I benefit from RAII, much better string handling that C, the STL-type template classes, O-O features, and other advantages it has over C.
–
David ThornleyDec 22 '10 at 20:45

17

@Blagovest: No, you don't. For example, what you've mentioned is insufficient to achieve RAII, and the container classes have functionality that is beyond simple hand-crafted data structures. If you think that's possible, you never learned C++ well.
–
David ThornleyDec 22 '10 at 21:29

4

@Jaroslaw I fail to see why multi-core machines would put OOP to the grave. If you mean C++, I could see where you were coming from. OOP is a fundamental concept in many modern programming languages, especially high-level languages. Even C can be OO, if you program it that way. Its just not as convenient as C++ IMO.
–
vedosityDec 24 '10 at 1:34

When I first looked at Git source code two things struck me as odd:
1. Pure C as opposed to C++. No idea why. Please don't talk about portability,
it's BS.

YOU are full of bullshit.

C++ is a horrible language. It's made more horrible by the fact that a
lot of substandard programmers use it, to the point where it's much
much easier to generate total and utter crap with it. Quite frankly,
even if the choice of C were to do nothing but keep the C++
programmers out, that in itself would be a huge reason to use C.

In other words: the choice of C is the only sane choice. I know Miles
Bader jokingly said "to piss you off", but it's actually true. I've
come to the conclusion that any programmer that would prefer the
project to be in C++ over C is likely a programmer that I really
would prefer to piss off, so that he doesn't come and screw up any project I'm involved with.

C++ leads to really really bad design choices. You invariably start
using the "nice" library features of the language like STL and Boost
and other total and utter crap, that may "help" you program, but
causes:

infinite amounts of pain when they don't work (and anybody who tells me that STL and especially Boost are stable and portable is
just so full of BS that it's not even funny)

inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but
now all your code depends on all the nice object models around it,
and you cannot fix it without rewriting your app.

In other words, the only way to do good, efficient, and system-level
and portable C++ ends up to limit yourself to all the things that are
basically available in C. And limiting your project to C means that
people don't screw that up, and also means that you get a lot of
programmers that do actually understand low-level issues and don't
screw things up with any idiotic "object model" crap.

So I'm sorry, but for something like git, where efficiency was a
primary objective, the "advantages" of C++ is just a huge mistake.
The fact that we also piss off people who cannot see that is just a
big additional advantage.

If you want a VCS that is written in C++, go play with Monotone.
Really. They use a "real database". They use "nice object-oriented
libraries". They use "nice C++ abstractions". And quite frankly, as a
result of all these design decisions that sound so appealing to some
CS people, the end result is a horrible and unmaintainable mess.

I don’t think Linus should be the guy to go to for arguments here. His rants are horribly subjective and immature. He actually does have a few good points but they are so deeply buried (below “bullshit” as well as bullshit) that they are very hard to find.
–
Konrad RudolphDec 22 '10 at 14:55

17

Haha, that was a good laugh. I never want to meet this guy.
–
Felix DombekDec 22 '10 at 15:40

28

Linus reminds me of a very talented roofer who's never hung sheetrock, but calls the sheetrock guys pansies because they use screws instead of nails.
–
Bob MurphyDec 22 '10 at 17:09

5

Linus has a point but expresses it way too harshly to be taken seriously.
–
Blagovest BuyuklievDec 22 '10 at 22:27

31

I agree with @Daniel, If there is someone that can talk about pushing the boundaries of hardware is John Carmack creator of doom, quake and other games and founder of Id software. He writes this about c and c++ on a twitt a few months ago: "IMO, good C++ code is better than good C code, but bad C++ can be much, much worse than bad C code." twitter.com/#!/ID_AA_Carmack/status/26560399301
–
OnemaDec 22 '10 at 23:21

What about embedded development? Python isn't always available, and the difference in speed between C and well written C++ is negligible on devices past a certain level of processing power. Of course, I suppose a C++ compiler wouldn't always be available either...
–
JamesDec 22 '10 at 14:48

I agree with this answer, do the high level with python, since you will write it something like 3 times faster, profile, and then release bottlenecks by replacing them with C/C++. It's redundant to say "replace bottleneck with C++ code" since you won't do any high level with the code you need to be fast, since it will be low level code. There is one thing: i don't know how to interface c++ with python :/. but in term of time spent in front of the screen and efficiency, I think that's the best solution, since most of the C++ code will be fast for nothing !
–
jokoonDec 22 '10 at 22:43

6

Go work for a big financial company and build a complex financial system in a big distributed team in Python and see how you like it. The experience will teach you: a) advantages of type safety, b) advantages of compilers saving your butt, c) LUDICROUS code that Python allows noobs to write. People say that it's easy to shoot your foot with C++ -> some python stuff can work but be borderline insanity. Right now I would so much rather work in C++...
–
MrFoxSep 27 '12 at 17:49

1

@suslik: Wow, I'm shocked that anyone would actually use python for that kind of system. I agree with you about bad noob python code; I've seen some myself.
–
Larry ColemanSep 28 '12 at 15:53

Some people might simply prefer using C++ over other options. Asking if there's a reason to use C++ is like asking why we need to have hundreds of flavors of ice cream. Not everyone likes simply sticking with Vanilla.

If developers already are very competent with C++, the question for them may not be 'why use it?', but rather 'why not?'. There seems to be this trendy anti-C++ thing going on in SO right now, but believe it or not, not everyone subscribes to that. Some people may simply like C++ better than the other languages.

Does C++ need to be used for apps? Of course not. But this same exact question can also be asked for any other language. There are very, very few cases where a particular languages needs to be used for an application.

Also much less flexible. References (C++-style) are good at simplifying certain common constructs in a language that also has pointers, but they fall so far short of being a replacement for pointers, it isn't even funny. And your example is not-at-all a good case for references.
–
Ben VoigtDec 25 '10 at 23:11

@George: Because nothing changed, except it's two (count 'em) characters shorter? It's not solving any problems, it's not highlighting any pitfalls, it doesn't even do anything cool like extend the lifetime of a temporary variable (which references are good at).
–
Ben VoigtDec 26 '10 at 2:16

3

@George: "the reference is always valid" is flat out false. I'll give an example if you need one, but I'm hoping that you're expert enough to already be aware of this. And I'm not talking about forming an invalid reference using an invalid pointer, either. Functions that use pointers need documentation stating the preconditions on the arguments. But practically speaking, all functions need that level of documentation, so it's absurd to call that a strike against pointers.
–
Ben VoigtDec 27 '10 at 0:47

For server side programming you can often choose from a myriad of different languages, compiled or interpreted. Usually the choice of language is driven by which platform you or your team will be most effective on. Or if you don't yet have a team, the availability of skills in the market.

On a side note I don't really understand deciding to use C/C++ based on performance (only) since many scripting languages are extensible with C/C++. You get the benefit of a rapid development language coupled with the ability to migrate the slow portions into C/C++ extensions. Certainly if your doing systems programming where every op counts it's understandable, but in most app development I don't get it.

The thing to keep in mind while choosing a language, is what benefit you will get from using it, and how long it will take to get it.

The main idea between languages like python and perl is to do more with less man time, but with more cpu time. In fact you will spend more time coding a python or perl script than it will be executed, but you get my point.

The advantage of C/C++ is that they are fast, but at a cost of syntax and strong typing: you have to do a lot of thing yourself so that the computer has not to choose it at compile time.

When you make a code, some lines will be ran a lot more than others, and those lines are the one that pose a problem. On the other hand, all the rest of the code, the one you spent a lot of time on, is executed much much less often.
You might have heard it, but it is the infamous 80/20 rule, and you won't be able to bypass such rule.

The solution to this problem, is to use an easier language (by easier I mean more developer friendly: less typing, lazy interpretation, a lot of preexisting routines and stuff, etc.) to do all your code.

You will do it so quickly compared to if you would have done it with C or C++, it would have taken much more brain ache.

Your program will be slow, but with a profiler, you isolate the part which are ran 80% of the time, and you do them with C or C++.

By prorgamming this way, you saved a lot of time, and your program is as efficient, as much fast, has much less chances to leak memory, and you saved time.

Scripting languages were designed to be on the side of the developer, but optimisation is still possible. Of course you can be a design pattern magician or a STL voodoo or even a lisp warrior, and maybe an haskell monk. But languages makes us talk to computers, languages are not made for us to BE computers !

C++ vs Python vs Perl can't be judged easily. It depends on the project and requirements.

C++ has an arsenal of utilities from long ago, running in many platforms. But it is painful to start walking through streams for just passing String to Integer and reverse.

C++ on the other hand, has an awful deal with dependencies on libraries. Once you compile something in GCC X or VC++ Y, then you can't rely that the code will run by the next version of those tools. The same hell is on Windows, the same hell is on Unix too.

Perl, takes its power from Unix world but especially as a regular expression tool. This is what it is used most of the time. Along with some pretty serious tools that even Java can't do it in a normal way (check out how to upload a file to a web server), Perl is "just do it".

Python is easy, flexible and a dynamic language. So easy that you can send an integer to a function, the script expects string, yet you can have a result! Unexpected though, but a result. So it the programmer needs to be very cautious. IDLE offers some debugging, but when you have TELNET'ed to a system, or SSH'ed in three levels down and you want to find your problem, the debugger won't be there to stand next to you. But, it can do some great math work fast.

Java is an ecosystem of buzzwords, alien technologies, and big words and when you want to just upload a file to webserver, you find that you can do it only if the server has JSP.
If you want to call system libraries or system functions like monitoring you find that you have to dig out a lot. And perhaps to reach JNI and OK...you think then..."Why, Lord?"

Apart from that, Java is a great tool for business suites, and multithreading, I liked it a lot.

Fast to make a program and show to your CV "Oh, I know that technology too" and your want-to-be boss, be amazed! Even though, the technology might not be that needed... (OK, folks, I hate the Spring Framework....)

There's actually a single answer to all questions formed like this. The best reason to use tech X instead of tech Y (where X and Y are roughly on the same level [like just about all contemporary programming languages are]) is because you already know X and don't know Y.

(but after Haskell arrived, there has been no reason to use anything else)

No, not at all. If you don't need the performance and there is a library you can use the other language then don't bother with C/C++. I only do it nowadays when I target embedded systems that can't (easily?) run languages. Sometimes I use C because I am writing a plugin but really no.

However, I wouldn't use Python, Perl, etc. to avoid using C. My preference is actually C#, because I like a good library (which is a strength of .NET), and I like statically typed languages. Boo is a good alternative. But really Haskell, OCaml, D, ML and such are all fine.