What's wrong with C++ compared to other languages?
[Please support Stackprinter with a donation]
[+70] [51] krebstar
[ c++ ]
[ http://stackoverflow.com/questions/385297] [DELETED]
I'm a novice programmer and have recently found a job doing C++ development... I've noticed that a lot of people seem to REALLY hate C++, calling it outdated/stupid/inefficient/whatever.. Personally I haven't really noticed any bad traits, but then that may be because I haven't had experience in anything else and I'm not experienced enough in it to discover its flaws..
So the question is: What are the pitfalls of using C++, so I'll know what to look out for.. Is it simply the lack of memory management or is there something else I'm not aware of?
Does being a C++ programmer make me somewhat stupid in the eyes of other programmers?
EDIT: Just to make my question clearer, what are the traits of C++ that make people hate it so much? I know it's somewhat hard to learn, I don't know a lot of things about it yet, but so far it hasn't seemed like an insurmountable challenge..
EDIT: All answers seem to be similar, and that is C++ is hard but makes some things possible that isn't in other languages. I guess what i'm getting from this is that programmers hate that C++ is hard..?
EDIT: I am not trying to start a flamewar here people! Okay, lets be more organized..
I want answers in this format:
Pitfall: Cause: Alternative (in other languages):
Pitfall: Lack of Memory management
Cause: You have to manually allocate and deallocate memory.
Alternatives: (Java) Has automatic garbage collection. Cleanup happens when the pointer is not being referenced to anymore.. JUST AN EXAMPLE, not sure how it is implemented..
EDIT: Guess We can forego this format..
(1) c++ certainly has it's pros and cons, but anyone who says that inefficiency is a "problem" with c++ has no idea what they are talking about. You should likely ignore their opinion and find someone who does know what they are talking about. - Evan Teran
(4) Yeah, "what i'm getting from this is that programmers hate that C++ is hard" is a fair summary... ;) That's really what it all boils down to. - jalf
(3) Oh, about inefficiency as Evan says, that depends. Programmer time is a resource like any other, and C++ tends to use a lot of it. ;) So depending on your definition, C++ may be very inefficient. :) - jalf
Fine, to clarify myself. I was refering to runtime efficiency. In fact, if anything languages like java/c# and all similar have built in overhead which will likely never outperform c++ in the general case (yes in some specific cases it can, but this is a general purpose language...) - Evan Teran
I had originally upvoted this question but removed my upvote as I think insisting on Pitfall/Cause/Alternatives is unproductive. Maybe I'll be shown wrong, in which case I will re-upvote. - Norman Ramsey
@Norman, I think (insisting on pitfall/cause/alternative) might be a bit more productive than just letting everyone say whatever they want.. Then it just becomes a mess and people start talking on different levels :(.. We want people to talk on the same level so that we can rate the pitfalls easily. - krebstar
(1) Evan: A problem with C++ (runtime) efficiency is that it's easy to create a lot of unnecessary overhead. If you're not careful, you'll create temporaries all over the place for example, which is a performance hit you don't naturally get with Java or C#. So C++ can easily become very inefficient. ;) - jalf
And like Normal said, removing my upvote because the format is unproductive. There's a lot of useful information in the answers, and I know I'd have to write 3 times as much if I had to reformat my answer under this format. And for what gain? - jalf
I see.. hmm.. If you guys want it that way, then ok.. Do whatever you want.. I'm removing chosen answer and you guys can vote on which answer you guys think is most relevant to the question.. - krebstar
(1) Damn, this thread has gotten so big its hard to read >.< Can someone close this? Lets just say C++ has its pros and cons and leave it at that :(.. I shoulda known better than to ask such a vague question :( - krebstar
(1) Don't close it. I think there is value here. Don't be discouraged by the ramblings... There is a lot of useful information in here as well and valid points. - Mat Nadrofsky
Okay.. just say when if you guys want me to pick an answer.. - krebstar
@jalf: all languages have the ability for the developer to write inefficient code. c++ is no exception, there are plenty of ways like you say to write bad c++ code. But a poor programmer can write shitty c# too! So I wouldn't consider than something "wrong" with c++. :-P - Evan Teran
[+111] [2008-12-22 01:29:00] Johannes Schaub - litb [ ACCEPTED]
Please don't believe people that say C++ is bad. Often those people compare C++ to languages that aim to solve different problems than C++.
C++ follows the don't pay for things you don't need philosophy. It's therefore inappropriate to compare C++ to Java or C# which target simplicity and flexibility (think about reflection, for instance).
The point of C++ over C is that C++ allows you to take the advantages of object orientation and the power of generic programming to build cleaner and more concise code than you would do in C (In my opinion. Of course many C programmer think otherwise. But that's life). But it won't protect you from shooting yourself in the foot. Maybe that is what the aforementioned people don't like. One doesn't know.
In trying to do what it does, C++ has become quite confusing in some areas and intricate. So it still makes sense for programmers to just stick to plain C, if they don't feel like learning C++ while they are quite comfortable with C.
Believing there is a reason for the majority of undefined behavior cases, let's look at some others answers undefined behavior cases, and try to explain reasons.
// information about size lost, because we care about the lost size and performance
int* p = new int[10];
int* p0 = p + 11; // undefined behavior, because information of size is lost,
// we can't test.
int* p1 = p - 1; // Undefined behavior, again for the same reason.
// undefined behavior. I don't know why they haven't forced the implementation to
// give a diagnostic. Beyond me. Recent gcc versions warn (at least) anyway.
cout << i++ << " is less than " << ++i << endl;
// not undefined behavior, but the result of the cast is unspecified. This is
// so that if one knows the behavior of an implementation, one can provide optimized
// code running faster by doing that pointer conversion. The Standard say for a
// similar reinterpret_cast case: "It is intended to be unsurprising to those
// who know the addressing structure of the underlying machine."
cout << reinterpret_cast<float*>(p); // undefined behavior
const int c = 42;
const int& r = c;
// just casting away const is not undefined. but writing to an const
// object is undefined behavior. still, no space and performance is lost by
// storing information about the constness of the object somewhere
// (which would require runtime type information)
const_cast<int&>(c) = 43; // undefined behavior
// same argument: we don't want to do a check for overlapping region, and
// we want to keep being compatible with C. Maximal performance, minimal safety.
memcpy(p, p+1, 9); // undefined behavior, overlap
Can you tell me what areas C++ has become confusing? - krebstar
(5) programmers frequently find it confusing that "this" is a pointer but not a reference. another confusion is why "hello" is not of type std::string but evaluates to a char const* (pointer) (after array to pointer conversion) - Johannes Schaub - litb
That only shows that it doesn't use the same conventions as other (later) languages. - le dorfier
I'd call the "this" thing a pretty trivial issue though. And oops, thanks for catching a few errors in my examples of undefined behavior. :) Although I don't understand what info about size has to do with anything in the first one. A pointer is simply not allowed to point outside allocated memory - jalf
Is this a constant poiner? - yesraaj
this can be constant if the method is const int getFoo() const; <- in the scope of getFoo, "this" is constant, and is therefore readonly. This prevents bugs and provides some level of guarantee to the caller that the object won't change. - Doug T.
(1) you can't reassign "this". i.e you cannot do "this = &other;", because this is an rvalue. but this is of type T*, not of type T const . i.e it's a non-constant pointer. if you are in a const method, then it's a pointer to const. T const . but the pointer itself is nonconst - Johannes Schaub - litb
(2) think of "this" like this: #define this (this_ + 0) where the compiler creates "this_" as a pointer to the object and makes "this" a keyword. you can't assign "this" because (this_ + 0) is an rvalue. of course that's not how it is (there is no such macro), but it can help understand it - Johannes Schaub - litb
int* p0 = p + 11; What's undefined about this operation? I can see that dereferencing p0 would be undefined. - Andomar
(2) Andomar, if you add a value to a pointer to elements of an array, and the result will be a pointer that does not reference an element and not one past the end of it the behavior is undefined. that simple :) - Johannes Schaub - litb
anyway, i've found a good quote about all this (esp the last, memcpy): "The programmer knows in a great many cases that the two blocks cannot possibly overlap, so the space and time overhead are for naught." :) lysator.liu.se/c/rat/d11.html#4-11-2 - Johannes Schaub - litb
Andomar, the reason probably is that it can't know whether or not it hit a "trap representation". the bits comprising the value of a pointer are not necessarily built up like a number. they could have structure with bits having individual meanings. - Johannes Schaub - litb
(5) There is no reason to write C++ that way if you don't intend to deal with the resulting undefined behavior. You can use std::vector for arrays, memcpy is a C function, and all of those casts are bad uses of C++ casting. - Bernard
(1) @andomar, int* p0 = p + 11; points 2 elements past the array. Even if you're not dereferencing the pointer, you are only allowed by C and C++ to have a pointer pointing 1 element past an array. - nos
@jalf, the size is not present in the type of int*, so no diagnostic can be given at compile time. The Standard does not require a diagnostic at runtime either because pointer arithmetic and checked arithmetics bite each other. - Johannes Schaub - litb
[+72] [2008-12-22 03:06:05] Daniel Earwicker
C++ is a systems programming language. That is, it is especially suited to writing operating systems (sometimes even drivers, with certain constraints) and anything that has similar requirements to an operating system - very direct control over performance-sensitive characteristics, absolute parsimony in use of memory or CPU cycles.
For that purpose, C++ is the best thing there is. There are people who claim C is better because it's simpler - the Linux kernel folks for example. Looking at how you allocate a dynamic array of structs in C vs the equivalent std::vector declaration in C++ makes me doubt that claim. C++ provides some complex tools which can be used by library designers to make life simpler for systems programmers.
But... so much for systems programming. C++ is, today, an inappropriate tool for general purpose application programming. I used it for that purpose for over a decade. I never want to go back to it. It just doesn't make any sense. In general purpose development, the number one rule is do not optimise prematurely. The whole philosophy of C++ is based on microscopic optimisation at every opportunity, before you have any evidence that its worthwhile. It's a recipe for painful, difficult labour with no actual economic benefit.
The irony is that it frequently ends up being slower than Java or C# as a result of these basic assumptions.
The std::string class was originally intended to support copy-on-write semantics. This means that when one string is assigned to another, the two objects share the same buffer, until one of them modifies it, at which point they stop sharing. This all happens behind the scenes to speed up your program. Then vendors realised that they needed to make it thread-safe, a subject the C++ standard was silent on at the time. So they put locking into the string class. This made it perform appallingly on multi-core machines, so they took out the copy-on-write optimisation. Back to slow copying! Meanwhile the need for copy-on-write doesn't even arise in Java and the CLR because they use immutable string objects directly accessed by references, providing inherent thread safety.
A similar situation exists now with boost's shared_ptr, now part of the language standard. It has to use interlocked operations to increment and decrement reference counts. This has a high cost on multi-core machines, and the world is going multi-core in a big way. It's a half-hearted attempt to provide something akin to GC, but it will never be able to compete with the real thing, and it's only going to get worse as multi-core scaling becomes vital.
For widely-used rich client applications, you need to write Windows applications. The ideal platform is the CLR, which provides a vast ecosystem of libraries, plus the language of your choice, the two major choices today being C# and VB. Both are fine, with C# appealing the most to people like me because yield return is the Awesomest Thing Ever. Or you can use Java - it has suffered over the years from horrible support for GUIs and a language enhancement process that is slower than molasses, and yet it is still better for developing desktop applications than C++.
For server-side apps, you are typically not writing "system" code. The most popular websites in the world are hardly ever written in C++, although the bare-metal HTTP server may have been. They are often written in dynamic languages like PHP, although Java has made some headway and ASP.NET isn't unheard of (this site, for instance).
There was a brave attempt by the chair of the C++ standards committee Herb Sutter to develop a huge set of extensions to C++ known as C++/CLI, designed to ensure that C++ was a true CLR-enabled language. But the extensions were so rich and complex that the result was really a completely new language that inherited all the complexity of C++ as well. And it is only used in practice to help with interfacing between old C++ code and new CLR code, not for general development; consequently it is a tad over-engineered.
So there you have it. If you're writing an OS or something that routes packets on a network, the raw plumbing, as it were, C++ is the best thing there is.
But let's face it, you're probably not doing that.
(1) +1, Thanks for this.. However it is a little too long and hard to digest, plus this wasn't supposed to be an argument of C++ over C or vice versa.. Other than that, Good stuff on the string class comparison between java and C++ - krebstar
I welcome suggestions on which parts I should delete! - Daniel Earwicker
(1) I mentioned the comparison with C to support my claim that C++ is the best thing there is for systems development, which is bound to be contentious. - Daniel Earwicker
(6) I also welcome comments from downvoters. - Daniel Earwicker
Earwicker, why not try to make separate answers detailing each pitfall.. :) - krebstar
(2) Because I'm more interested in reading people's textual responses than collecting votes (up or down). - Daniel Earwicker
Okay.. :) But I thought the point of this was to make a list of pitfalls and how to avoid them, then let the most popular, therefore most important, pitfall to avoid float to the top.. Then novices like me can know what's REALLY important to know :) - krebstar
(1) Nice answer. Lot more concise than mine. ;) - jalf
(1) It's not actually possible to detect that intent from your question. It says at one point: "Specifically, what I'm asking is, what are the things C++ can't do and should be better left to other languages? If so, what language is that?" Which is what I answered. - Daniel Earwicker
Thanks jalf, appreciated! - Daniel Earwicker
Sorry earwicker, maybe i should rephrase the question.. - krebstar
+1 i like your answer too. shows nicely the two sides of the coin (system and business programming). and this copy avoiding also is the reason for the move constructors and rvalue references in c++1x. yet another feature to get more performance at the cost of clearness. but it's boosting performance - Johannes Schaub - litb
where c++ is superior to c: how c++ can help gcc's codebase: airs.com/ian/cxx-slides.pdf usage of c++ in the gold linker: airs.com/ian/gold-slides.pdf . both by expert ian lance taylor. - Johannes Schaub - litb
I'm not aware of any guarantees on the speed of std::string. All that is vendor specific. I am aware that some string implementations require a #define to enable thread safety. Other compilers use machine specific assembly language to assure that reference counting is as fast as possible. - community_owned
(2) Juan, machine-specific assembly language for reference counting can't hide the cost of obtaining a consistent view between the caches of two cores. This is an expensive operation at the hardware side, and this is the cost that immutable strings save you. - Diomidis Spinellis
(2) I've just realised I never even got on to the perils of a flat memory model, unchecked at the basic level. This is probably the number one problem with C++, far worse than manual memory management. - Daniel Earwicker
@Earwicker, what is a "flat memory model"? - krebstar
(1) Means that the memory accessible to a process can be accessed as if it were a single enormous array of bytes (or of any other type, in fact). Safe languages instead present memory as little separate pieces, and never let you access the space on either side of them. - Daniel Earwicker
(2) I specifically disagree that the sharedptr is a "half hearted attempt at garbage collection". In my own opinion the shared pointer is what garbage collection should have been. It is deterministic and allows you to take over management of memory if it doesn't fit. - Jon Trauntvein
(6) Garbage collection also allows you to take over memory management. You just allocate a big array of bytes and write some functions to suballocate from it. Also shared_ptr is only technically deterministic, not usefully so. What we want in deterministic cleanup is to be able to say... - Daniel Earwicker
(1) I'm not sure you're right on the c++ string v Java/C# string. Java/C# tend to copy those strings all over the place. That the GC is a faster allocator is what makes it perform acceptably. - gbjbaanb
(4) "By this point in the code, cleanup has occurred." With shared_ptr that can be very hard to prove because the object may be shared and hence still alive - else why bother using shared_ptr? It's used in situations where you don't care too much about when cleanup occurs - just like GC. - Daniel Earwicker
The thread safety is not right either - J/C# are quite inefficient at threading, because they try to be safe. run a C# app on a multi core and a single core box - the 1 core will run 4x faster (though, obviously most real-world apps have other bottlenecks). - gbjbaanb
(2) Java and C# never make copies of strings unless they need to be modified. They also automatically optimise concatenation for common cases, and provide auxiliary classes to allow you fine control when building strings. You can also work safely with a character array in really tight situations. - Daniel Earwicker
(1) That comment about C# having negative scaling across multiple cores is so obviously not true, it's barely worth point it out! - Daniel Earwicker
I've done it, look at Jon Skeet's website about singletons; run the same code there on different cpu configurations and see for yourself. Ok, its a 'benchmark', but it shows that something is going on under the covers you wouldn't expect. - gbjbaanb
(1) But a thread-safe singleton in C++ has exactly the same scaling properties (I've certainly tried that). It's not at all unusual for a multithreaded C++ program to run slower on multiple cores until it has been profiled and tuned properly. This is nothing to do with C# vs C++. - Daniel Earwicker
For "something that routes packets on a network", the language of choice is C, not C++. Cisco routers don't usually crash, which they would if they had C++ code:) - Andomar
(2) @Andomar - what's the use in folkore? Explain how C++ makes bugs appear in programs where C doesn't? - Daniel Earwicker
(8) From everything I've heard, boost shared_ptr is fast. Irregardless, any feature in the standard libraries of Java or C# can be implemented in C++. Even the GC in Java and C# can be implemented in C++. As a matter of fact, I'd be surprised if their GC's weren't written in C++ or at least C. - Bernard
(12) Any feature of those libraries can also be implemented in hand-generated binary machine code, if you're feeling really masochistic! - Daniel Earwicker
Awsome answer dude, and I couldn't agree more, nice one. - Binary Worrier
(1) I argue that CoW + thread-safety is easily doable without a lot of impact on performance. Atomic integer operations are supported by all modern processors in some form or another and that is basically what is needed - atomic reference counting. Qt has CoW for nearly all classes and the overhead won't be felt AT ALL, as there's a billion other much slower things in a program. - iconiK
(1) @iconiK - interlocked operations are not free. If they are used frequently, they will absolutely destroy scalability in many-core hardware. And one well-known attempt to add reference counting back on to the CLR's GC (apparently in the hope that this would provide deterministic clean-up) resulted in a system so slow that it was impractical to wait for it to build itself in order to perform a complete performance test. 66.102.9.132/search?q=cache:JsND76WUmeAJ:www.sellsbrothers.com/… - Daniel Earwicker
@Earwicker - Nevermind, I did not take into account multiple cores or processors. In that situation, interlocked operations are pretty damn expensive. For general stuff it will be fine, for high-performance applications, oh well :| - iconiK
[+42] [2008-12-22 03:46:04] Norman Ramsey
Your question is difficult to answer because for most programmers, the problem with C++ is the whole of the language, not individual pitfalls. Bjarne Stroustrup is on record as saying that he started "C with classes" because of a bad experience using Simula-67 and not being able to control the costs of memory management. So minor pitfall #1:
Many programmers think that with today's hardware and today's garbage collectors, the potential gain from explicit memory management is not worth the potential for introducing bugs. Please note that explicit memory management is not always faster; years ago Ben Zorn did a great study on the costs of conservative garbage collection in C and C++ programs. (I don't know why memory management engenders such passion, but it does.)
Another reason programmers dislike C++ is its complexity. Poster child for complexity: templates. When templates were first introduced, some compilers got them wrong, and almost all compilers had wildly inefficient implementations. I worked with people from Stanford who had "templatized" their code and an application that used to build in an hour would not build in a day. When this happens to programmers, they stay angry for a long time.
Another poster child for complexity: the language spec was always changing and the compilers were always behind. It's really infuriating to plan on using an alleged feature and then find out it's not supported, or that it appears to be supported but does not perform well enough to be useful. In the early days of C++, this happened a lot. Eventually the community stabilized on just two implementations: free software uses GNU C++ and commercial software uses the excellent front end [1] developed by the Edison Design Group.
When almost nobody can implement a language successfully, that's a sign of a bad design. Programmers who have been burned remember, and in this case they rightly blame the language, not the compiler writers.
Another big reason that some programmers dislike C++ is that its design lacks intellectual coherence. C++ is a collection of features that were tacked on to C with only two criteria: somebody thought it was useful and if you don't use it you don't pay for it. This procedure is a recipe for a language in which the parts do not work together to form a harmonious whole. This is one reason people find the language difficult to learn. To learn more about the process by which C++ came about, check out Jim Waldo's excellent book on the evolution of C++ [2]. Waldo's book will give you a more balanced view than any of Stroustrup's apologia.
To sum up, the major problems people have with C++ are largely not individual pitfalls but rather
Early implementations didn't do what they said on the tin, and some programmers are still angry.
The language features don't fit together and the totality of the result is so very complicated that nobody can master it all. (Some C++ shops have fights over what subset to use.)
[1] http://www.edg.com/index.php?location=c_frontend
[2] http://rads.stackoverflow.com/amzn/click/026273107X
+1 Thanks, good post.. - krebstar
(3) blimey, you can say all of that about C# - its changed so much it bears little resemblance to .NET 1.1! - gbjbaanb
Edison Design Group as "settled" compiler for commercial C++? Not Microsoft VC++, not Borland, not Intel? What the hell is EDG? What did I miss? - Arkadiy
(5) It's been 8 years since I worked on C++ compilers, but in 2000 most vendors (including I believe Borland and Intel) bought C++ front ends from EDG rather than develop their own in-house. They were naturally not keen to publicize this fact. Had I not worked with EDG I would not have known. - Norman Ramsey
(1) I've read Comeau's compiler's the one which most faithfully implements the C++ standard, even more than GCC. GNU's C++ is fine except their non-standard "features" (some of which I consider frankly idiotic and running against the spirit of the languages). - Joe Pineda
Agreed on both points about EDG: They do a very good job, but their clients may be reluctant to talk about it. I am allowed to say that my former employer (PalmSource) used EDG's front end for its compiler, and that they did a very good job (I reported some bugs in it, but relatively few). But it took months to get our lawyer's permission to write an article on our compiler testing; without that, I'd be forbidden to discuss it by my NDA. - Flash Sheridan
Another example which I can apparently talk about, since Professor Engler already has: Coverity uses EDG as well: (stanford.edu/~engler/spin05-coverity.pdf): "We use Edison Design Group (EDG) frontend. Pretty much everyone uses. Been around since 1989." - Flash Sheridan
(1) Agghhhh.... why all the shouting? It's hard to read your answer - I get the idea of marking important stuff in bold... but half of the text? - viraptor
(5) "When almost nobody can implement a language successfully, that's a sign of a bad design." So true, so true. - JesperE
(2) @Joe Pineda: Interestingly, EDG lists Comeau Computing among its customers (edg.com/index.php?location=customers_oc) - mlvljr
[+36] [2008-12-22 01:44:38] jalf
DISCLAIMER: litb has made some very good points in the comments to this answer. C++ should not be compared to python or C#. They're targeted at different areas of work. C++ is very well suited for the things it is used for. C# is very well suited for the things that is used for. Neither language can be considered "obsolete" or "inefficient" at the things they're meant to do. However, people who make statements like "C++ is obsolete and inefficient" usually try to make this comparison, to prove that C++ is not suitable for modern applications development. As litb said, this isn't a very meaningful comparison, but people still try to make it. So this post will do the same, to look at how C++ compares to languages like Java, C# or Python. Modern high-level RAD-like languages on their own home turf. In other areas (systems programming, low-level stuff on embedded devices and so on), C++ stands practically unrivalled (well, C and C++ does), there can be no doubt of that. But for high level business programming, C++ lacks a lot of niceties that other languages provide.
The problem is that nearly everything is a pitfall. It's a very versatile and powerful language, but it also lets you shoot yourself in the foot in hundreds of subtle ways that more "modern" languages don't allow.
About being outdated, the language lacks a ton of modern facilities. Look at the .NET class library, or Python's standard library. Both offer a huge set of functionality for pretty much anything you'd ever need. C++ has.... A few streams and a few container classes. (Yes, that's a bit of an exaggeration) Other languages have garbage collection to free the developer from worrying about memory management, C++ doesn't. So in many ways, C++ is outdated. It's missing a lot of tools that more modern languages have. But of course not in every way, and there are areas where C++ is the best tool we have.
C++ being stupid? Most definitely. There are a couple of notable blunders in the standard, such as std::vector<bool> doesn't behave as a vector, the export template keyword that virtually no compiler supports and a few others. The syntax is so complicated as to be almost impossible for a compiler to parse. Compile-times can grow to be huge because of this. The compilation model is nothing short of archaic (header files? Come on, we don't live in the 70's)But more importantly, writing correct C++ code is just ridiculously hard, because many instances of things that look harmless and compile without a warning actually rely on undefined behavior. The following are all examples of undefined behavior. They compile just fine, and they might usually work, but they may also format your harddrive, set fire to your computer, print all your porn to the office printer, or crash the program:
int* p0
int* p0 = p + 11; // undefined behavior, pointer out of range
int* p1 = p - 1; // Undefined behavior, as above
cout << i++ << ++i << endl; // undefined behavior, may not modify variable multiple times between the same sequence points
cout << reinterpret_cast<float*>(p); // The result of the cast is unspecified *except* tht if you cast it back to int*, you get the original value
const_cast<int&>(c) = 43; // undefined behavior // casting away constness from a variable that was initially const is undefined.
memcpy(p, p+1, 9); // undefined behavior, memcpy between overlapping memory
And of course many many more (and much more subtle) issues exist.
As for being inefficient, people often say that C++ is extremely efficient. And it is. I can't think of a better language for high-performance code. It beats C in many cases, and while Fortran may be a bit faster for purely numerical tasks, that gap has almost been eliminated by clever use of template metaprogramming and expression templates. C++ is damn fast. But again, only if you use it correctly. It is very easy to write inefficient C++ code, whereas something like C# is reasonably efficient no matter what you throw at it. To illustrate, check out this series of blog posts: http://blogs.msdn.com/ricom/archive/2005/05/10/performance-quiz-6-chinese-english-dictionary-reader.aspx
Two high-profile Microsoft bloggers competing to write the fastest version of a simple program, in C++ and C# respectively. The C++ version ultimately wins, but only after a huge amount of extra work, and a few extra bug creeping in. In almost every iteration until then, C# keeps pace easily. Apart from that, it's an enlightening and entertaining read. Check it out.
Anyway, by asking what the pitfalls of C++ are, you're really looking at it the wrong way. By default, assume everything in C++ is a pitfall. Only trust code that has been verified against the standard. And of course, that makes it virtually impossible to trust your code if you're not already a C++ expert. ;) The best advice I can give to avoid the pitfalls is to really try to learn the language. Read the C++ questions here on SE, get a copy of the standard (and get some practice in looking things up in it. It's not an easy read), buy a book like the annotated reference and so on.
And no, if anything, being a (good) C++ programmer might make you look impressive in the eyes of others, simply because getting good at C++ is a huge undertaking.
Overall, there are good reasons why C++ can be considered all these things you mentioned. But not in every case, and overall, the language has some unique strengths that no other language has so far duplicated.
Edit Oops, looks like I angered the One-True-Language Brigade. Perhaps you should actually read my answer before saying that "virtually nothing in it is correct". All I do is list a bunch of facts. The C++ standard library is missing many everyday features that .NET provides. Where's my threading library? Sockets? Regex? And the things I listed are undefined behavior. Rico Mariani and Raymond Chen are high profile MS bloggers, and Mariani in particular is one of MS's performance gurus. And they did make a series of blog posts demonstrating the relative performance of C++ and C#, and the outcome was what I said. Those things are simple facts. And if you don't think vector<bool> is stupid, I'd really like to hear your reasoning.
I'm sorry if I angered anyone who only knows one language, and feels that therefore it must be perfect. But C++ is not perfect. I like the language, but I don't have any illusions that it's perfect, or that it doesn't lack a lot of modern conveniences.
(1) "c++ is outdated" . you missed to say for what purpose it's outdated. - Johannes Schaub - litb
+1, Hmm, I guess an answer to my question is probably impossible to answer as it might take a whole book just to list them all, huh?.. anyway, I'm choosing this as the answer.. :) - krebstar
(6) I can't believe this answer has been accepted. Virtually nothing said here is correct. - Nemanja Trifunovic
@Nemanja - Oh... :( I wouldn't know for sure.. :( I'm just a novice :(.. Care to explain? - krebstar
(3) "Look at the .NET class library, or Python's standard library. Both offer a huge set of functionality for pretty much anything you'd ever need." Lmao, nothing I need (except for things like primitive types) is in the .Net framework. :( - TraumaPony
@TraumaPony - I don't think that is meant to be taken literally.. But I wouldnt know.. - krebstar
(4) Sure there's bad, but then there's the good stuff, to name a bit: Good C++: Templates, boost, standard lib, extensive 3rd party lib support, RAII, access to C primitives, cross platform is completely possible, manual mem. management optional but allowed. Plus nobody writes code like above. - Doug T.
What about memory consumption? How much extra memory do virtual machines take up? - Doug T.
(1) Okay, will un-answer this until I see there is a better answer.. - krebstar
litb: I said it's outdated because of the things it's missing. GC, comprehensive standard library. And yes, there's the good stuff too. That was the point I was trying to make. C++ has a truckload of shortcomings, but it also has advantages that make up for it. - jalf
(1) Edited my post. Wilhelmtell and Nemenja, care to give some examples of things that are "completely wrong" in this post? - jalf
wilhelmtell: Not true. Where's the performance penalty in the .NET GC? 15 years ago, you were correct. Today, GC's can be made pretty damn efficient, and in some cases, more efficient than manual memory management.. - jalf
(3) i'm not going to say everything you wrote is wrong. i'm just saying you compare c++ with c# isn't going to be useful. for example c++ doesn't have a big standard library because it wants to keep the burden for implementors small. so for example it provides a "freestanding" library. - Johannes Schaub - litb
(1) which only includes the very basic stuff to support language features (INT_MAX and stuff and variadic macros for example). - Johannes Schaub - litb
(1) so i asked you for which purposes it's outdated. if you say it's outdated for programming microcontrollers, i wouldn't agree for example.but i would agree if you say it's outdated for high level business programming.and i agree with you that vector<bool> is a mess. one should use std::bitset instead - Johannes Schaub - litb
I think the comment about std::vector was a victim of SO's markup problems - jalf has updated it to say std::vector<bool>, which any C++ expert will tell you is the craziest class ever. - Daniel Earwicker
wilhelmtell: Reread please. I forgot to mark it as code, so it removed the angle brackets. I meant to say vector of bool. Sorry about that one. ;) litb: right as always. My point was just that it can be considered outdated for the reasons mentioned. But it is not a universally true statement. - jalf
wilhelmtell: Missed my point about bogosort. Of course the compiler doesn't get a say in the algorithms you use. But badly written C++ code will generate numerous calls to copy constructors, assignments and so on, or allocations with new, things that are basically free in C#. - jalf
Yes, I could tell.... It is just a language, and hell, even Bjarne Stroustrup doesn't pretend it doesn't have its fair share of shortcomings today. Although he also points out they were added for a (usually good) reason that made sense at the time. - jalf
Geez calm down people! Jalf is right, he was just pointing out some things that might cause undefined behavior that a novice programmer might miss.. Why dont you guys do what he's doing instead of bickering and nitpicking :( - krebstar
thanks for updating your answer. i didn't want to start a flame war :) i'm sorry if it sounded like "hey stop trapping c++" :) dunno why he dropped the answer mark away from your answer. i think it explains why people say c++ is bad. - Johannes Schaub - litb
Yeah, I admit some parts of the original answer were badly phrased, and losing the angle brackets around vector of bool was unfortunate. I together, I can see why people might have disagreed with that. :) - jalf
"High profile" and "Microsoft" in the same sentence? If you can't see a rigged performance comparison you don't deserve the title of programmer! - Matt Joiner
(1) @Matt: what exactly is not "high profile" about Microsoft? And if you can't explain what is rigged about a performance comparison when you see it, then you don't deserve to have your opinion heard. Show us that this more than blind, childish MS-bashing. - jalf
(3) A performance test comparing C++ and C# by Microsoft, is not believable. For starters they control both implementations they're testing, and intentionally deprecate C++ in favor of C# due to its relatively high usage on non-Windows platforms, something they wish to stamp out. - Matt Joiner
(1) @Matt: A performance test is not believable if you can find flaws in it. Can you? (And saying they "deprecate C++" is just absurd. Have you looked at how much work they put into C++ in VC2010? Obvious troll is obvious. Go back to slashdot. Or just grow up and you know, show us how their perf comparison is invalid. You have access to the code written by both. Can you find problems with them that intentionally favors one language? Do you get different results when you run the code? - jalf
(1) There are websites where the mere taint of Microsoft is enough to get anything declared in valid. StackOverflow is not such a website. Here, you're going to have to provide evidence of the flaws in a performance test if you want to show that it is invalid. Who wrote it, and who they worked for while they wrote it, is not relevant if you can't find flaw in the actual data. - jalf
(1) @jalf: I have better ways to waste my time than try to fight the C# horde, no thanks. I won't believe it. I have used VC2010 extensively (no choice: vendor monopoly), and they missed over half of it, and got more wrong (I challenge you to find the mistakes if you'd like to waste so much time). Make your own decision. - Matt Joiner
(1) @Matt: that doesn't even make sense. Missed half of what? Got what wrong? What are we even talking about? There's also no monopoly. You can write Win32 apps using other compilers. And I think you're missing a point here: presumably, since you're willing to stick out your neck and call the performance comparison I referred to invalid, you've already "wasted" the time to find the actual flaws in the comparison, right? Otherwise, you're just trolling, and that's obviously not the case, right? So, since you already spent time finding flaws in it, go ahead and tell us what you found. - jalf
(1) @Matt: what's more, their conclusion fits very well with mine: most C++ code sucks. Most C++ code is surprisingly inefficient. It takes a lot of effort to write fast C++ code, and very little effort to write reasonably fast C# code. Hence, if you don't spend ages optimizing the code in either language, your C# implementation will likely be faster. And if you do take the time to optimize, then eventually, C++ will become faster. Exactly as their performance comparison showed. - jalf
(1) But since you don't want to "waste" time backing up your claims, any attempt at convincing others that you're right is implicitly a waste of time too. You can't do that without showing us some data backing up your claims. And hence, every comment you've made here is also a waste of time. Not just yours, but mine as well. And the time of the next poor sucker who happens to read your trolling. - jalf
(1) No, I'm offended that you think my time is yours to waste. I'm offended that you call yourself a programmer, when you're so obviously incapable of looking at code and judging it on its own merits. If you can only judge it based on the company that employs the person who wrote the code, then you are not a programmer. - jalf
@jalf People like that aren't worth your time. And look at the "answer" given below by the person who said "Virtually nothing said here is correct" -- simply too foolish to be concerned with. - Jim Balter
[+33] [2009-02-15 19:58:48] Konrad Rudolph
What's wrong with C++ is its syntax. Very, very wrong. For some good and other not so good reasons the syntax is completely contorted, complicated, unreadable and in a few cases downright ambiguous. Of course the standard clears these ambiguities but the rules are (seemingly) arbitrary and these cases should have been prevented in the first place.
I'll give two examples which I find classical and which illustrate the core issue.
First, templates. (Unintentionally) introducing a Turing complete language that executes at compile-time was both a stroke of genius and madness, since it allows very complex expressions. Consider:
/* 1 */ a <  (b) > (c)  > (d);
/* 2 */ a < ((b) > (c)) > (d);
What does this do [1]? Notice that both are well-defined C++ with two definite meanings (for matching types/variables a…d).
More generally, I've got a bone to pick with the C++ committee for their design of declarations and definitions. A bumbling band of baboons couldn't have done worse. (And with all due respect, I stand by this statement!)
Consider the following list. Try to know/guess for each line what it does.
a b;
a (b);
(a) b;
(a) (b);
(a b);
(a (b));
a b(0);
a b();
a b[];
a b = a();
(a *) (b);
(a) * (b);
(a) (* b);
a (* b)();
a b(c);
a b((c));
This is madness!? No, this is C++!
Note that these codes have got different meanings depending on whether a is a type or a variable! Let's take a look … I've replaced a with the type int for clarification.
int b: Declares the variable b to be of type int.
Two possibilities:
int (b): Performs a function-style cast from b to type int.
var (b): Calls operator () on object a and passes argument b.
(int) b: Performs a C-style cast from b to int. This is equivalent in all but name to the function-style cast. Notice that this is true even for non-POD when the constructor is called.
(a) (b): Two possibilities; like 2.2 and 3, respectively.
(a b): Syntax error.
(var (b)): Like 2.2.
int b(0): Defines the variable b of type int with the value 0.
int b(): Declares the function b of prototype int (void).
int b[]: Declares the variable b of type int[] (i.e. array of int).
int b = int(): Defines the variable b of type int and assigns it the value 0. For a that are POD, this call emulates the default constructor syntax.
(int *) b: Performs a C-style cast from b to int*.
(a) * (b): Multiplies a with b. Duh.
(int) * (b): Performs a C-style cast from *b to int.
(int) (* b): Ditto.
int (* b)(): Declares the variable b of type "pointer to function with prototype int (*)(void)".
int b(c): Declares the function b of prototype int (c) (and here, c is interpreted as a type, never as a variable, even if there is no such type).
int b((c)): Defines the variable b of type int and assigns it the value of c. More generally, this calls the constructor passing one argument (c).
Notice in particular how sometimes parentheses have got a meaning while being optional at other times. In case 16, the inner parentheses look completely redundant even for professional C++ programmers: in order to disambiguate between types and variables, variables may always be wrapped redundant parentheses, while types may not. This is the reason for the completely different semantics of statements 15 and 16.
And this doesn't even touch on arcane matters like macros, trigraphs or templates. These are all plain vanilla statements/expressions that might be found in any old code.
By the way, the above also gives ammunition why C-style casts should, always, ever be avoided in favour of the more verbose new style C++ casts.
[1] http://stackoverflow.com/questions/52506/c-template-ambiguity
+1. however, I would add the ambiguity that references lead to. - Comptrol
Sorry for waking up this old answer, but I think I found a bug in 2) xD int(b) will declare a variable b of type int, it won't cast. Only in (int(b)) it will. This is once again going to prove how confusing C++ syntax is :) - Johannes Schaub - litb
[+29] [2008-12-22 02:12:18] Fabio Ceconello
As others have said, C++ IS REALLY HARD TO LEARN. More than that, it's a two-stage learning. First, you have to learn all the language features. Second, you have to learn how to use them wisely. Most people never get to the second stage, and hate the language forever.
But in many cases, though, it's "religious" hatred. This is particularly common between some Java programmers I know, which believe Java came to replace all the other languages, is better than them, and C++ in particular (for some reason) is the major evil. They don't state this directly, of course, but it's not hard to get it.
I love C++ and do most of my job in it, but also feel having to mention that C++ does have many flaws in its design, though, so much that there's a book about it, Imperfect C++ [1]:
None of them, of course, should be reason to thrash it (therefore the book). But also none of its strengths should be the reason to use it when another language is a better choice. I, for instance, would always consider Java, Ruby, PHP, etc. as a better choice for a website backend than C++. To automate simple tasks, I'd go for scripting languages... and so on.
[1] http://rads.stackoverflow.com/amzn/click/0321228774
Good one.. I'll try to check out the book when I can.. Thanks.. - krebstar
Unfortunately with Ruby and PHP, whenever you need to enforce type safety you must do it at run time, you must also do it explicitly. This can be a liability. Regardless, every language requires the same kind of learning however few compare with the complexity of C++. - Bernard
[+25] [2009-03-30 09:37:12] Comptrol
According to Linus Torvalds, " C++ is a horrible language [1]".
Yet again, Steven Dewhurst [2]'s response [3] to his critisicm.
I think it's only fair to point out that Linus' diatribe is more than a year old, and he has spoken in more measured and printable tones elsewhere about the same subject. Less excusable, however, is that he makes the claim that C++ cannot be used in resource-constrained areas with nothing but anecdotal evidence to support his claim. Linus has done good work and has earned his soap box, but he also has a professional obligation to make sense while he's holding forth. (For those who follow such things, this is an instance of Gotcha Chapter 12, "Adolescent Behavior," from C++ Gotchas.)
The argument that abstraction and efficiency are mutually-exclusive or that they're mutually exclusive in the context of C++ is demonstrably false. Lately, much of my work involves writing embedded code in C++ with heavy use of inheritance and templates, and the results have been more than promising. The resultant code is typically smaller and faster than the equivalent (well-written) C code provided by the board's manufacturer, and has the significant advantage of being usable by a developer who is not expert in the minutia of the board's design. Unlike Linus, I haven't written a commercial OS, but I have written a policy-based, pre-emptive tasker in C++. It occupies just 3k of RAM and is pretty zippy in addition to being easy to understand, customize, and maintain. Just to annoy people like Linus, I've also used typelist meta-algorithms to generate exception handlers with identical efficiency to hand-coded C. In a number of recent talks given at the Embedded Systems conferences, I've shown that commonly-criticized C++ language features can significantly outperform the C analogs. As an old-school, Bell Labs C hacker I've nothing against C. But C++ provides tools and capabilities that are hard to come by in C, and often make it easier for a competent C++ programmer to produce cleaner and typically smaller and faster code than the C equivalent.
Regarding competence, Linus's implied argument that C++ attracts bad programmers the way other things attract flies is, in spite of the effective metaphor, both unfair and a little over the top. Inexperienced or incompetent programmers have been lured into writing bad code in other languages as well; I've inherited my share of poorly designed and rendered C. There's no question that C++ is a significantly larger and more complex language than C, and a competent C++ programmer should be familiar with many more design styles (including, among others, that "idiotic 'object model' crap") than a competent C programmer. Wider experience with different design approaches and coding idioms is an advantage if the programmer actually has more than a passing understanding of the techniques. Problems typically arise when teams of competent C programmers are thrown onto a C++ project without adequate preparation simply because C++ syntax looks something like C syntax. The results are usually about the same as you'd get by throwing the same team into a COBOL project. But you're not going to catch me criticizing COBOL. That's Linus's job.
[1] http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918
[2] http://www.informit.com/store/product.aspx?isbn=0321321928
[3] http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=411
The response is garbage. C++ generates "nice", "optimal" code purely by coincidence. You have to chance on the right combination of templates, classes etc. that don't result in the compiler hitting some recursive definition and pumping out 3MB binaries. - Matt Joiner
[+19] [2008-12-22 01:19:40] community_owned
I use C++, instead of C, because I like having classes as first class objects.
I like C++ because I can call anything I want written in Fortran, C, and C++.
I love static typing.
I appreciate it's undefined behavior, because it allows optimization opportunities for the compiler.
Resource Acquisition is Initialization (RAII) is your friend.
You are listening to the wrong people. C++ is optimized for certain applications, but is not so good for others. Use the right tool for the right job.
Hmm, I'm gonna need to do some research on all the stuff you've mentioned.. I don't know what first class objects mean :P - krebstar
Fortran? Really? You mean you can call compiled library code written in Fortran, or a C++ compiler will understand Fortran source code? - Bill the Lizard
I wouldn't know anything about this, don't know fortran.. - krebstar
You can call compiled Fortran code or C code if you understand the calling convention for your platform and you use extern "C" to keep the function name from being mangled. C doesn't have a concept of a class. C++ does have a concept of a class. - community_owned
[+17] [2008-12-22 01:20:32] Andy Hume
I don't think you should take anyone that says C/C++ is "outdated/stupid/inefficient/whatever" too seriously.
It's true that a lot of people may be using higher level languages for certain tasks these days, but it really depends on what you are doing. In many situations C is the best and right tool for the job.
I'd also suggest that learning lower-level languages like C is a great foundation for becoming a better programmer. You're working closer to the CPU, and understanding more about how processes evolve on a machine. This kind of knowledge will improve your understanding and give you an advantage when it comes to designing systems and architectures, even in higher-level languages.
In many ways, C++ is outdated and stupid, and to some extent and by some definitions, inefficient as well. You should definitely take such claims seriously. They just don't automatically make C++ a bad language. In some areas it's the best there is. - jalf
@jalf - These "ways" you mentioned are exactly what I'm trying to find out :) - krebstar
wilhelmtell: the vector of bool specialization is not stupid? A standard that no compiler actually follows strictly is not stupid? Undefined behavior is not stupid? Virtually unparsable syntax is not stupid? Mars rovers are irrelevant. You can build some amazing things with stupid technology. - jalf
C++ is an organically gronw language. Bits and pieces have been added to it over the years, and sometimes they've been huge successes (templates),other times, they've been epic failures that even the standard committee recognizes (vector of bool, export template). - jalf
Why should you insist that a language that has it's main purpose pay-as-you-go should behave 100% the same on all machine platforms? The two concepts are antithetical. There's nothing stupid about undefined behavior or strict standards compliance, which of course is outside the committee's control. - ApplePieIsGood
I'm not sure what exactly your beef is with the specialisation of a vector<bool>. The interface to the container does not change at all and it can provide an amazing amount of compactness to represent boolean values as single bits. - Jon Trauntvein
C++ is not growing fast enough, and should change its name to reflect departing from its C heritage. - Matt Joiner
[+16] [2008-12-22 02:03:25] Nemanja Trifunovic
C++ is hard to learn and that's why some people hate it. I like it because it lets me do my job and does not hold my hand. If I screw something up, there is only one person to blame for it - me.
(3) I can't agree more. - Eduardo León
[+11] [2008-12-22 02:29:40] Chris
I could write an long rant, but it amazes me this question comes up so much as it does.
There is nothing wrong with C++, it's only in the programmers head :).
As for it being outdated... If you're using Firefox or Google's Chrome to view this page, you using an app written in C++.
The main pitfall of C++ is it makes you read and understand before you go and start to hack together a program. There are many ways to learn C++ and to implement C++, that perhaps, is one confusing aspect of C++. Once you have the language semantics down, the rest is just following them to complete your task.
Actually there are big chunks of Firefox in Javascript and XUL. The C++ part is the Javascript interpreter and the XUL engine. - Jason S
(2) Yes, this is true, but for the most part those apps are C++. - Chris
[+10] [2008-12-22 13:10:51] gbjbaanb
Pitfall: It doesn't have a very fashionable garbage collector!
Cause: RAII
Alternatives: manually call dispose() or close() methods through your code, or scatter every scope block with the using() equivalent. Alternatively force a GC collection regularly, or wait paitently for the GC to kick in and finalise your object.
How can garbage collection "kick in" by itself? What are dispose() and close() methods? do you write these yourself or is there some sort of call that I dont understand? - krebstar
the GC does stop your app and do its collecting thing on its own terms, at its own time. That's a problem with it. Close() I meant as a generic 'do the cleanup' method the object would have implemented itself. - gbjbaanb
? You must be confused between C++ and C#. C++ doesn't have garbage collection. RAII in C++ is quite straightforward with destructors. - Jason S
oh, see the smiley please. - gbjbaanb
(2) You can implement a GC in C++. Anyway, GC would be a terrible thing in a hard real time system. If the GC kicks in at the same time your "fly by wire" fighter jet is supposed to respond to the joy stick controls to pull up, it could kill the pilot. - Bernard
An alternative to GC could be using smart pointers (like the ones in boost library), they clean themselves up. - Emile Vrijdags
(3) +1 for the irony :) - Mladen Jankovic
[+10] [2008-12-22 20:13:39] Arkadiy
I find C++ FQA Lite [1] to be a good compilation of problems with C++.
[1] http://yosefk.com/c++fqa/
(2) I don't. If it ever was at one time, it's obsolescent at best. - David Thornley
(2) It's hilarious and very insightful. - Matt Joiner
[+9] [2008-12-22 15:24:17] David Thornley
Speaking as a C++ fan, here's what I see as problems.
First, the language is complicated. There's a lot to learn, and implementors are often slow to add new standard features. The cause is that the language evolved rather than was planned out, and languages like Java were more planned.
Second, there's no central big library. This is probably due to the Unix philosophy of offering a lot of choices, so there's plenty of different libraries here and there. This contrasts to Java's huge standard library, and Perl's CPAN.
Third, people tend to learn the wrong things first. In this list, and the Frequently Questioned Answers rant, people complain about things that can be easily managed with standard strings, smart pointers, container templates, namespaces, etc. This is partly due to the size of the language, which makes it hard to learn everything fast, and the history which makes people usually learn the more C-like parts first. Other languages (Perl excepted) tend to have more standard ways of doing things.
Fourth, programming well with C++ requires more skill and knowledge than other languages. Stroustrup designed it to be usable for almost anything, and its evolving nature means that you have to know more to use C++ safely than most other languages. There are more recent languages that cut off the complications (pointer arithmetic, multiple inheritance), and concentrate more on making the language safer to use at the expense of some expressiveness the designers don't like.
(2) Learning the C-like parts first is useful because the core language is C-like and the high-level stuff is just grafted on. You can write std::string str = "Hello, world!\n", but if you don't know about pointers, you won't understand why std::string str = "Hello, world!" + '\n' isn't equivalent. - dan04
[+9] [2008-12-22 03:32:27] Matt Briggs
Best description of C++ I have ever read was from Steve Yegge's Tour de Babel [1]. I also really love his description of Perl from the same article
C++ C++ is the dumbest language on earth, in the very real sense of being the least sentient. It doesn't know about itself. It is not introspective. Neither is C, but C isn't "Object-Oriented", and object orientation is in no small measure about making your programs know about themselves. Objects are actors. So OO languages need to have runtime reflection and typing. C++ doesn't, not really, not that you'd ever use.
As for C: it's so easy to write a C compiler that you can build tools on top of C that act like introspection. C++, on the other hand, is essentially un-parseable, so if you want to write smart tools that can, for example, tell you the signatures of your virtual functions, or refactor your code for you, you're stuck using someone else's toolset, since you sure as heck aren't gonna parse it. And all the toolsets for parsing C++ out there just plain suck.
C++ is dumb, and you can't write smart systems in a dumb language. Languages shape the world. Dumb languages make for dumb worlds.
All of computing is based on abstractions. You build higher-level things on lower-level ones. You don't try to build a city out of molecules. Trying to use too low-level an abstraction gets you into trouble.
We are in trouble.
The biggest thing you can reasonably write in C is an operating system, and they're not very big, not really. They look big because of all their apps, but kernels are small.
The biggest thing you can write in C++ is... also an operating system. Well, maybe a little bigger. Let's say three times bigger. Or even ten times. But operating system kernels are at most, what, maybe a million lines of code? So I'd argue the biggest system you can reasonably write in C++ is maybe 10 million lines, and then it starts to break down and become this emergent thing that you have no hope of controlling, like the plant in Little Shop of Horrors. Feeeeeed meeeeeee...
If you can get it to compile by then, that is.
We have 50 million lines of C++ code. No, it's more than that now. I don't know what it is anymore. It was 50 million last Christmas, nine months ago, and was expanding at 8 million lines a quarter. The expansion rate was increasing as well. Ouch.
Stuff takes forever to do around here. An Amazon engineer once described our code base as "a huge mountain of poop, the biggest mountain you've ever seen, and your job is to crawl into the very center of it, every time you need to fix something."
That was four years ago, folks. That engineer has moved on to greener pastures. Too bad; he was really good.
It's all C++'s fault. Don't argue. It is. We're using the dumbest language in the world. That's kind of meta-dumb, don't you think?
With that said, it is obviously possible to write nice C++ code, by which I mean, code that's mostly C, with some C++ features mixed in tastefully and minimally. But it almost never happens. C++ is a vast playground, and makes you feel smart when you know all of it, so you're always tempted to use all of it. But that's really, really hard to do well, because it's such a crap language to begin with. In the end, you just make a mess, even if you're good.
I know, this is Heresy, with a capital-'H'. Whatever. I loved C++ in college, because it's all I knew. When I heard that my languages prof, Craig Chambers, absolutely detested C++, I thought: "Why? I like it just fine." And when I heard that the inventor of STL was on record as saying he hated OOP, I thought he was cracked. How could anyone hate OOP, especially the inventor of STL?
Familiarity breeds contempt in most cases, but not with computer languages. You have to become an expert with a better language before you can start to have contempt for the one you're most familiar with.
So if you don't like what I'm saying about about C++, go become an expert at a better language (I recommend Lisp), and then you'll be armed to disagree with me. You won't, though. I'll have tricked you. You won't like C++ anymore, and you might be irked that I tricked you into disliking your ex-favorite language. So maybe you'd better just forget about all this. C++ is great. Really. It's just ducky. Forget what I said about it. It's fine.
[1] http://steve.yegge.googlepages.com/tour-de-babel
(2) Slight problem with that is the comment about STL and OOP. The STL is not actually OO. It's more like abstract data types used as a basis for functional programming. The algorithms are pure functions and function objects are like really inconvenient lambdas. Clearly its designer was an OO sceptic. - Daniel Earwicker
(1) I just read half of Steve Yegge's rant about Lisp. What he described there is not a language problem. It's a quality of developer program. Of course the system written by one of the best software engineers in the world is going to be better than the one created by a room full of code monkeys. - bobwienholt
Oops... s/program/problem - bobwienholt
(1) I love the "you don't build a city out of molecules" remark. That sums up why layered systems exist. - Soviut
@Nemanja Trifunovic Nope. He claims it isn't smart. - Maciej Hehl
(2) You know, it sort of makes me sad that someone calling steve yegge a joke got six upvotes. It's sort of like calling jwz a slacker, or paul graham a moron. There are a certain class of people that are deserving of respect, even when you disagree with them. Steve Yegge falls into that class. - Matt Briggs
This answer is awesome. The rant is spot on. - Matt Joiner
[+7] [2008-12-22 09:41:50] obecalp
C++ allows you to construct all sorts of abstractions with minimal performance penalty. No other languages come close in this regard. There're problems/defects with it, as it's a complex language and the specs and implementations can have bugs/defects, just like most other languages (even python, ruby, php etc. have many bugs you have to work around.)
Other than that, the main problem is complexity, as it's a multi-paradigm language that allows you to do all kinds of things in sometimes verbose and somewhat non-intuitive ways (which gets better after you understand/practice a little more.)
However for applications where bottle necks are else where (external services/db etc.), the performance advantage of the language is negligible and doesn't worth the extra effort.
OTOH, I personally find my productivity in C++ (with the help of the excellent boost libraries) is on par with that in other languages (including Java, Python, Ruby, Perl etc.) for large performance sensitive applications, because you end up pulling your hairs out if they are too slow and you have to rewrite parts of it in C/C++, which is usually a PITA to deal with (all foreign languages interfaces I have used have been a PITA (mostly due the maintenance need of upgrades these other languages), including simpler ones like those in Tcl, Lua and Ocaml, compared with using the same language). For short one liners, my favorite is still Perl, as it's ubiquitous and more consistent than shells.
(1) THis is good.. Any good scripting languages you recommend to supplement C++? I was looking at Python 3.0 but not sure which one is easier to learn, etc.. - krebstar
I think that lua tends to have the "cleanest" interface because of its base design so far as a "built-in" language. - Jon Trauntvein
Games developers have adopted lua as the standard script language to support the C++ core code, so it might make a lot of sense to go for that one just because there's a lot of C++/Lua out there. - gbjbaanb
[+7] [2009-02-13 15:59:44] dsimcha
To me C++'s complexity is actually justified to some degree by the fact that it's a multi-paradigm, performance-oriented language. I think its biggest downfall is that it's engineered only for performance and flexibility, and is missing a ton of little convenience/syntactic sugar features. In other words, it just makes very little effort to make simple things simple, leading to death by a thousand cuts. Examples:
A good, but trivial, example is the ridiculous amount of boilerplate necessary just to iterate over an STL container.
A really, really basic standard library. Yes, you can go find third-party libraries, and this is fine when you have some large monolithic need. However, when you need a bunch of small, miscellaneous pieces of functionality, the overhead of finding libraries and keeping track of all these dependencies is hell.
An antiquated module system that requires you to violate DRY by including prototypes in headers, thus telling the compiler the same thing a zillion times.
No delegates, closures, etc. Sure, you can simulate these with other language features, but it's a lot more of a PITA to use than if they were first-class concepts.
This is only a problem because the nature of C++ is to rely so heavily on metaprogramming where less performance-oriented languages would use something like runtime reflection or duck typing, but the template system is a Turing tarpit. Variadic templates, static_if, etc. would make C++ metaprogramming much more useable.
Lack of GC. Yes, GC isn't appropriate for everything, but it's appropriate for most things. If C++ GC was opt-out, not opt-in, I think it would simplify things greatly, while still allowing real-time programs, embedded code, etc. to be written in C++. Admittedly, though, with RAII and smart pointers, lack of GC isn't as bad as it sounds at first glance.
I'm sure I could think of more, but these are just my biggest, most obvious complaints.
[+6] [2009-03-14 15:49:21] Agnel Kurian
C++ will not spoon-feed you. If that is a problem, then yeah, it sucks. :)
[+6] [2009-05-11 17:37:06] finnw
C++ is big and complicated.
But that's not the problem.
Because it's big and complicated, many companies/departments hire a C++ guru. The job title is often "Application Framework Architect" or something similar. This job, unfortunately, attracts people who are not easy to work with. They usually don't write low-level code but do write high-level, excessively-generic templates that don't really do anything. They also write coding standards. And since they haven't written any low-level code in years, they easily forget that they making other developers jump through hoops (or maybe they enjoy doing so.) So you end up with silly rules like "switch statements are banned" and "all database access must go through my (broken) ORM template library." And it's politically unwise to argue with them because they are assumed by management to always be right on any C++ issue.
This is less of a problem with simpler languages, because there are fewer subtleties that the guru could claim to be the only one to understand.
+1 for _ high-level, excessively-generic templates that don't really do anything_ and _ it's politically unwise to argue with them because they are assumed by management to always be right on any C++ issue_ - Matt Joiner
[+6] [2008-12-22 07:55:14] Fortyrunner
Speaking as someone who does a lot of maintenance work:
Other peoples C++ can be very hard to parse. There is a lot more scope for self expression and that can be quite dangerous!
Memory management is certainly an issue, a good C++ programmer can produce amazingly fast and efficent programs in C++ maybe more so than any other language.
In my experience there aren't that many of those guys around and the casual C++ programmer can cause a lot of damage in fewer lines than in (say) Java or C#.
Unless you have a high degree of technical competence it can be much harder to produce cross platform code: libraries, word sizes etc will trip you up.
This is good, although could be structured more clearly.. +1 - krebstar
Thanks. You are right - I have edited it a little - Fortyrunner
[+6] [2008-12-22 16:35:09] bobwienholt
Maybe someone else has already said this but...
Language only matters to a point. The best programmers can create great systems in crappy languages and the worst programmers can create crap systems in the greatest languages. I've seen it time and time again... and it's the most annoying thing in the world.
[+6] [2008-12-22 02:01:13] Michael Burr
C++'s drawbacks are mainly that it is quite complex. A lot of that complexity extends to syntax (especially in the area of declarations, initialization/construction, and in particular templates). A lot of the syntactic complexity is in the language because the designers were committed to keeping the syntax as backwards compatible with C (and early, pre-standard C++). Quite simply, there are an awful lot of rules to using C++ properly, and a lot of those rules are 'special cases'.
There is also a lot of complexity in terms of resource management -it's entirely the programmer's responsibility. RAII helps a lot with that, but until Boost-style smart pointers and other RAII management classes become universal and/or standard, RAII techniques will be done differently in different projects making them painful to adopt (everyone seems to roll their own).
The advantage of C++ is that the programmer is largely in complete control. And as far as potential performance goes, there are few things that would require dropping down to assembly to get performance that can't be done in C/C++.
Thanks, but quite general.. I was looking for more specific examples.. - krebstar
Unfortunately, there are so many pitfalls to list (even though I like C++). Entire books have been written about them. A couple good places to start are the C++ FAQ Lite (parashift.com/c++-faq-lite) and the C++ Frequently Questioned Answers (an 'anti-FAQ' - yosefk.com/c++fqa) - Michael Burr
Thanks :) Guess this will have to do :) - krebstar
The anti-FAQ is ridiculously argumentative and filled with terrible advice. It claims c++ exceptions are essentially worthless. Wth? Read any of Sutter's books, his chapters on exception handling in c++ will show you how wrong the Anti Faq is. - ApplePieIsGood
Yes, the anti-faq, was kinda weird, i don't think it would count as constructive criticism.. - krebstar
I didn't mean to say the the FQA has good advice, rather that it points to areas that might be 'pitfall' laden. While exceptions may be a nice error handling mechanism, they have their share of issues - note how much literature is devoted to exception safety. Handling errors is always hard. - Michael Burr
[+6] [2008-12-22 03:29:45] Daniel Paull
The single biggest problems with C++ is the separation of "platform" and language. That is, when you get a C++ compiler and the standard libaries, there is not a lot of standard utilities and frameworks that the developer can just jump in and use. This makes it hard for C++ to be marketed.
If you look through the marketing crap and compare language to language, not platform to platform, you will find that C++ is one of the best languages around, suited to many, many types of applications.
I personally dislike the way that C# and Java are tied to their respective platforms.
[+5] [2008-12-22 03:26:00] m3rLinEz
Here is mine ..
Pitfall: Lack of Intellisense support compared to C#, VB.NET
Cause: Without Reflection mechanism as in C#, VB.NET, it's hard for an Visual Studio to provide great insellisense/autocompletion of the same quality.
Alternatives: C# and VB.NET :)
Pitfall: It is hard to create GUI program with Win32 or MFC. Even third-party tools such as Qt or wxWidget is hard for a n00b to setup and understand.
Cause: Maybe because creating a GUI and handling events in VB 6.0, C#, VB.NET is so easy. So I see doing this in Win32, .., is hard.
Alternatives: We can actually create GUI in C# and have some background works done in C++ with C++/CLI. But this also adds dependency to .NET Framework :)
However, I always praise C++ programmers for their algorithmic expertise. But I don't see many C++ programmers who do software engineering practices or OOP concepts, in my life.
Good, thanks.. Maybe you can expound on reflection? For those of us who don't know what it is :P - krebstar
Try to make your answers like this.. When more answers are posted like this i'll unanswer this so that we can let the good ones float to the top.. Thanks - krebstar
What's the point of making the other answers like this one? You can choose "the" answer if you wish, but this is a subjective topic. The community benefits more from a variety of opinions. - Daniel Earwicker
The point is I want everyone to see this answer and restructure their answers the same way. Then we can see all the common pitfalls of C++ so that novices like me may avoid them. We can then proceed to vote on each indivual pitfall and i guess rate according to seriousness or severity - krebstar
Having longwinded answers does not necessarily show what pitfalls to avoid.. - krebstar
In my opinion, it's not that simple of a question. - Daniel Earwicker
It doesnt all have to come from one person.. It doesnt have to be complete.. Just say one pitfall and one cause, and how other languages avoid that pitfall.. That's all there is to it.. - krebstar
(1) Reflection lets you get information about an object's type, namespace, properties, functions... With this information the code editor can suggest what you can type following the object or class. You can generate ctag database to get such information for C/C++ classes. Good luck! - phi
(2) Reflection is not the cause of bad intellisense; it's a crappy compile-as-you-type parser that cuts (a lot) of corners for performance. - Jasper Bekkers
krebstar: The problem with this format is that you can't enumerate the pitfalls of C++ like this. Requiring this format owuld only make the answers even more longwinded. The same text is still required to explain the issue, but in addition we have to put in all this extra fluff. - jalf
Okok.. Oh well. I'm confused now.. I just wanted a sort of tips, things to watch out for in C++.. - krebstar
(2) Reflection allows you to get all info about your source code - types, structures, code etc. And your competitors get to see it too :) - gbjbaanb
(1) The difficulty in writing GUI code in C++ for Windows has nothing to do with the language. That is about the available libraries. Considering that Windows and .NET are commercial products of the same corporation (MS), I would expect it to work better there. An equivalent library in C++ can be made. - Bernard
If you buy QT its very easy to set up, just execute the installer and you get a visual studio plugin with it, so no makefiles or stuff. As for autocompletion, an alternative is the VS plugin Visual Assist, its very good at this job + provides some extra UI elements with VS to make reading code easy - Emile Vrijdags
[+5] [2008-12-22 02:07:55] utku_karatas
To name one pitfall - (arguable) lack of a proper module system. And solving the problem by preprocessor usage made things only worse IMHO.
Despite the popularity of C++ I must admit I have yet to see a proficient C++ developer in my not-very-long career personally. Knowing C++ will make you a more valuable player in the field for sure, let alone make you stupid in others eyes.
To give a broader explanation on "the lack of a module system", consider this example:
include <someheader.h>
x = afunction(...);
Now, there is no way to determine which module the symbol "afunction" comes from unless one goes and searches the declaration through the "someheader.h" and all the headers "someheader.h" includes and the headers those include and so on...
Of course, this is not much of a problem for your C++ compiler as it is given all the source code in a big junk of file(*) that is nicely prepared by the preprocessor, all the include directives expanding to actual sources they do point.
Now, it's debatable whether this is a better way to handle modules of source files compared to how other languages does and sure has its advocates for its usage but as far as I can see, this is one reason why C++ tools, let it be the intellisense feature in your IDE or any refactoring tool, are not up to par with say.. C# or Java tools. (Another reason would be the templates.)
(*) Citation needed. It would be nice if somebody enlightens us about C++ compilation cycle more intimately than this post does :).
EDIT: some funny quote supporting my experience.. [1]
C++ is like teenage sex:
* It's on everyone's mind all the time.
* Everyone talks about it all the time.
* Everyone thinks everyone else is doing it.
* Almost no one is really doing it.
* The few who are doing it are
o doing it poorly;
o sure it will be better next time;
o not practicing it safely.
ps. You may also want to look at the D language [2] which addresses the problems C++ faces in a more elegant and organised way. Reading through D documentation you may find comparisons to C/C++, explaining the pitfalls and alternative solution(s) D provides. Much recommended.
[1] http://www.softpanorama.org/Lang/Cpp_rama/humor.shtml
[2] http://www.digitalmars.com/d/
Care to expound on this? (The lack of a module system).. What is a module system? - krebstar
Just because you haven't met a proficient C++ dev doesn't mean they don't exist - I work with many, one of whom is a std lib contributor/maintainer. C++ is not easy, but that doesn't mean it's bad. Lack of a module system - huh? - jpeacock
(3) Modularity in C++ is knowing where to place your #include's. - Eduardo León
@jpeacock: I didn't claim they didn't exist :) it was just a remark on the fact that they're rare despite the popularity and maturity of C++ because of the hard-to-master characteristic of the language. I can name many .NET/Java gurus I know personally but not that many for C++. - utku_karatas
I'll edit the post for more on "lack of a module system". - utku_karatas
That's better :) If you could, can you please expound some more on how other languages achieve this? (determining which module a particular function belongs to) - krebstar
have you not heard of using namespaces? - David Allan Finch
the youth of today <sigh>, namespace != headers. You can define multiple namespaced classes in a single C# file, and so you end up still not knowing which 'module' a symbol appears in. - gbjbaanb
"Namespaces" is an answer to another problem - that is the global namespace pollution header system causes. - utku_karatas
utku karatas, could you expand your idea of modules, and show what you mean beyond C++ namespaces? - David Thornley
@David Thornley: IMO Java, C#, Pascal.. all have better defined modules/imports/code-organization/whatever-we-call-it architectures compared to C/C++'s preprocessor based solution. I guess "lack of a module system" has been too bold of a statement :) I'll put a disclaimer there! - utku_karatas
[+5] [2008-12-22 07:04:43] Alex Baranosky
This is a great question for me, because C++ was the first language I ever learned. It was a challenge to program in C++ in college. Then I learned LISP, that was totally different and still very challenging!!! Then I learned Python and Java. All I can say is WOW! The difference is in two areas, ease of coding and ease of use. You can't really see just how difficult it is to do simple things in C++ until you have used other languages that are so much more natural and ease-ful (not easy, but "full of ease", that natural flowing feeling)
I think of programming in C++ like lifting weights: once you can lift 200 lbs, then a push-up will be a heck of a lot easier. Or if you lived your life with weights on all the time (C++) then when you take those weights off, you're going to feel a whole lot lighter, and wonder what the heck you were thinking.
Pitfall #1: No Ease of Programming. Bugs happen much more often because you are dealing with lower level features such as pointers and *char a lot.
Cause #1: Directly accessing memory is something you can't avoid. Pointers used all over the place.
Alternatives #1: C#, Java, Python, Ruby, etc
Pitfall #2: No Ease of Use. Many common everyday things you might want to do, you will either have to code yourself or find some source online, whereas other languages have many more features built into their standard libraries.
Cause #2: Don't know. Maybe it is because the language is old?
Great job.. But it'd be better if more specific.. Like instead of "No Ease of Programming", say, "Have to directly access memory" or "have to deal with pointers and char * a lot".. or something :) - krebstar
It is mostly what everyone else has already said. You'll see the difference crystal clear once you sit down and learn one of those other languages I mentioned. - Alex Baranosky
(6) If you're having problems with pointers and char *, ur doin it rong. Use standard containers and std::string, and your life will be much easier. - David Thornley
[+5] [2010-06-24 07:45:24] stinky472
The biggest problem I see with C++ is the legacy it inherited from C. On top of that, it introduces a lot of unique runtime problems of its own which make it rather complicated to use across modules. For instance, exception handling and RAII, when used properly, can significantly reduce the efforts required for handling errors. Nevertheless, exceptions cannot be thrown across module boundaries. Memory cannot be allocated in one module and deallocated in another safely across module boundaries. This is true of C, but becomes a greater problem in C++ with template containers which can easily cause memory allocation/deallocation mismatches.
The lack of memory management isn't necessarily a weakness. The language provides you with the building blocks to implement any kind of memory management system you can imagine, and there are plenty of libraries available to do this for you. It doesn't have an integrated garbage collector like Java, yet one can develop one if desired.
That said, this is somewhat idealistic. Many programmers still continue to rely on manual resource cleanup in spite of having all the tools to automate it. Modern C++ thinkers like Sutter suggest going so far as to use nothing but smart pointers for all memory management so that there isn't a single instance in your code where you're manually freeing memory. This might seem excessive yet this kind of strict conformance is typically required for a team to successfully develop very robust, large-scale applications, especially when exceptions are involved.
A lot of the power of C++ is that it doesn't assume too much at the language level, allowing one to achieve very expressive code and even implement DSELs directly in C++. The lack of memory management enforced at the language level is but one example of this. The problem with that is that sometimes people try to get a little too creative and end up with something that might seem brilliant at the time but is actually very awkward and problematic to use in practice.
C++, being such a general-purpose language and one which makes very few assumptions at the language level, is a language which has great appeal to those who take it seriously. It is riddled with problems, but there's a tremendous difference which is probably one of the reasons it has die-hard enthusiasts like myself.
When we run into a language barrier in many other languages which causes systemic problems in the code your team produces, there's little we can do about it but work around it. As an example, there is no really elegant solution to deal with resource cleanup in Java and people often neglect to cleanup resources properly in the finally block. In C++, there are plenty of solutions available that people have built on top of the language (ways to implement RAII) since these kinds of things are not language-level problems in C++: while the language doesn't always provide solutions, it doesn't restrict solutions either.
This kind of freedom is probably one of the greatest appeals of C++ just from a pure language standpoint without considering other factors like efficiency. It has also lead to a lot of exploration and experimentation which has caused truly elegant and superior solutions to bubble up, yet those solutions are often awkward when it comes to implementation because they are built on top of such a general-purpose language with no specific accommodations for such solutions.
This kind of freedom is also the language's downfall. Too many self-proclaimed gurus tend to get creative and devise solutions to problems which have already been solved, and their solutions are often inferior to those which have been accepted and reviewed. Consider how many people have implemented their own reference-counted smart pointer in C++ without considering polymorphism, capturing on-site deletion, and the need for weak references. If C++ is going to move forward, more developers need to focus on the solutions that have worked and why they have worked rather than abusing the freedom that the language provides to roll their own solutions when superior solutions already exist. When it comes to C++, there's much more to learn than just the language itself; the freedom requires that we carefully study how it can be used effectively since there are too many ways to use it ineffectively.
The language also needs to evolve with these new discoveries and trends which it fortunately appears to be doing with C++0x, albeit slowly.
Very nicely put! - HighCommander4
[+5] [2009-04-04 17:12:57] Bernard
The greatest pitfall of C++ is the all C++ code that has been written incorrectly. C++ is incredibly complicated and it doesn't offer much of a buffer from the complexity of writing code. Many things are blamed on C++ that has nothing to do with the language and everything to do with the usage of the language.
To be fair developers are human, my C++ is far from perfect so I too have to pay close attention to ensure that I use it correctly.
Regardless, I would be highly critical of any "you can't do X in C++" statements as this is almost always false for at least three reasons: 1) C++ is Turing complete thus if a certain functionality can be computed then it can be written in C++. 2) C++ is fast, if you need to do X in Y microseconds on Z hardware then C++ is often times your best bet. Even if the compiler isn't good enough C++ supports inline assembly and it doesn't get much faster than that. 3) Most of what people describe as language features are actually standard library features. Those same libraries in Java and C# can be ported to C++. Even GC can be done in C++.
Also, while C++ is very complex there are ways to mitigate the complexity of it. With a good library (3rd party or in house) many things can be made much simpler. C++ offers an incredible amount of control over the implementation syntax (operator overloads, macros, templates). Furthermore, with good development practices the complexity of C++ can be managed.
Now, some may suggest that this complexity is a pitfall of C++. However, the complexity exposed in C++ exists in the other languages as well, some languages just hide these issues better by providing a prepackaged solution. This will allow you to make things work quickly, but once one of those more complex and underlying issues becomes a problem it still needs to be understood and fixed. In C++ you can still still do those kinds of fixes.
There are still many things that can be improved with C++ and there is definitely a need for extensions to the standard library. The syntax could be made more expressive, and the inclusion of C in C++ is a bit contradictory. Also the compilation model as someone else here suggested, may be in need of an update.
I really like what you said: "[...] Many things are blamed on C++ that has nothing to do with the language and everything to do with the usage of the language." +1 - stinky472
(1) My issue with C++ is that everything you can do wrong with the language, is provided by the ++ part. C is good enough. - Matt Joiner
That's not true Matt, pointers alone can cause plenty of trouble. Once you understand OOP you'll realize you've been doing it in C, just not as effectively. - Bernard
[+5] [2009-02-15 16:33:51] Tom Alsberg
C++ is sometimes very convenient and can ease development of some low-level code in C. Aside from various specific complications, the problem is that C++ is too often considered a much higher-level language than C, which is true in terms of the concepts and abstractions it recognizes, but those are mostly statically interpreted before actually compiling the code. In the way that the code is generated, it is almost as low-level as C. The compiler goes to a great length in trying to generate optimized low-level code equivalent to what the program specifies and hide the details from the programmer, but the details are there and have an effect in plenty of special cases which in practice requires you to take them into account.
Two main traits of the kind you had in mind follow:
Unclean function/module separation in generated code
Most classic compiled languages as well as modern "byte-compiled" languages, have the nice property of code generated by the compiler in so-called "units of compilation" - routines (functions or procedures) within modules (libraries, namespaces).
In C, for example, the body of every function can be compiled independently of that of every other function (of course the prototypes of functions and declarations of global data used need to be available to it, but those do not change when their implementation changes), resulding in text symbols (for functions) and data symbols (for global and static variables) in the generated object file. The code generated for calling a function is independent of the called function's code. This even extends to modules - different source files can be compiled separately into modules at different times (even by different compilers) and as long as they work and their interfaces (declarations and prototypes) do not change and the binary format is compatible (usually dictated by the operating system), one can be changed and re-linked (possibly at execution time) with the others.
In C++, this is not the case. Big parts of a program must be compiled together. Inlined code can span modules, code changes in small part of a class can change the code generated for many member functions, and users of the class, and big part of the code generated for templates is generated when compiling code that uses the templates (which is why in most implementations all templated code used externally needs to be implemented in header files). This can inflate executable sizes and compile times and make debugging more difficult. It also hinders modularity of compiled code (try distributing libraries that work with different compilers) and is largely incompatible with a main idea behind shared libraries - you can update one without having to replace or rebuild all programs that use it.
In practice this is not always a big problem - modern debugger technology often eases handling the generated code, big executables are tolerated if most of the code is not shared anyway, programs are tightly bound to one version of a library anyway, multiple versions of libraries can coexist, rebuilding is possible, and modern hardware and compilers are fast so compilation time does not necessarily matter so much. But this makes C++ feel very unclean, and in some cases when large systems are maintained, this can be a great pain.
Compile time problems / leaky abstractions
Pitfall: Many times, a small change in your code in one place can cause a much bigger change in the way code around it and types or objects used by it is treated, due to the great amount of static inference the compiler performs. Such a change can then cause the compilation to fail because this static inference does not work. If those details are ignored and the code at which the error occurs is inspected at the intended level of abstraction, there is no visible problem in it, but following the declarations will lead to an ambiguity or clash elsewhere. The error message generated by the compiler in such a case is likely to involve those static details that a real abstraction would not reveal, and to resolve the error you will need to understand them at that level.
Cause: The advantage is that even if the programmer is aware of those details, the compiler often takes care of them in an better way than the programmer would manually and unless a lot of attention is given, better optimized code is produced, while maintenance is simplified. Such errors often result from misunderstanding of the implications at some stage or insufficient care in the use of some language features, which is all too common. The programmer needs to understand the language well, be aware of those details and take care while writing such code.
Example: Compilation to fail where templates are used in multiple places, used elsewhere, due of infinite recursion at compile-time (which is of course detected by the compiler), resulting from a reference to a common type. Templates are designed to provide a polymorphic interface where compatible types can be substituted independent of the declarations behind them, but strictly the interface of a template is much more complex than the method signatures, involving all implicit types in the class definition.
Such details do not need to be inferred if they can be made explicit, requiring somewhat finer abstractions - this means more elaborate (and thus longer) code. This leads to a lower level interface closer to the actual semantics, and can to some extent be implemented even with features in C. In this case such errors are localized and error messages point where the clash is - which the programmer cannot be unaware of due to the explicitness of the interface. This is appropriate when low-level control and deterministic runtime of the kind that C++ can offer is desired.
Or, higher-level generated code (interpreted code, intermediate code that is not directly executable by the CPU, or a runtime abstraction library as used in Objective-C) can help better abstract such interfaces making them less leaky, redefining them in a more consistent way at the cost of avoiding some non-trivial static optimization that span large chunks of code. This results in somewhat slower code as some of the abstractions need to be handled by the interpreter or abstraction library at run-time. In some cases however this slower abstraction is either tolerable because it is not a performance bound or negligible because it is not a bottleneck.
In the case of intermediate code, just-in-time compilation in which optimization can be made at runtime based on such things as type information available, can be used to remedy this and result in performance that is often as good as statically optimized code. However, the increased complexity and non-deterministic performance can make it undesirable for some uses where low-level code would be desired.
[+4] [2008-12-22 07:43:13] RogerV
A lot of apologist for C++ have had their say. Here's mine:
I started programming in C++ around 1989/90. Presented a paper on enhancing C++ at OOPSLA '93. Interacted with Stroustroup regarding this enhancement, which he favored at the time. (Met up with him at conf. in Portland and started many months dialog from that point.)
Used C++ professionally up until probably writing last code in it around 2005.
These days in enterprise development I use mostly Java. Have also used C# for many things. I never really encounter anything anymore that would justify pulling C++ back out of the closet.
Bottom line for me is that Java and C# are both way more productive to write most kinds of entrprise-related software in than C++. Any claim that C++ attempts to make over performance, etc., is usually irrelevant (or not even entirely true given steady improvements in VMs over the years) - relative to the cost of producing the software. There is just not much occasion in the software I've written during this decade that C++ could make a viable argument for itself.
Folks that do commercial game software still rely heavily on it. Much of the serious OS kernel and related software is written in C (or Objective C). There is still some embedded development activity too for devices, etc. But in mainstream software, and particularly the web related and enterprise stuff, there's no need for, nor rationale that makes any persuasive case for C++. It's way too expensive to develop in relative to the much better alternatives.
(4) Since when was embedded software, games, operating systems, device drivers, video/audio codecs, simulations, telecoms, mobile phone software, etc etc any less "mainstream" than any other software? Just because it is not what you do does not make it a fringe activity. - Dipstick
(2) Well, these are entirely legitimate areas of software development. I merely meant that enterprise IT and web software are the predominate areas. The languages favored in those realms have shoved C++ aside for the most part, and continues to trend that way. - RogerV
@Dipstick, RogerV: You're both right. - Matt Joiner
[+3] [2008-12-22 01:24:47] Klaim
It's just that C and C++ are oriented to execution efficiency first, not programmer likeness first like some other languages. This fact make it hard to learn, so people hurted by the difficulty (like managing memory yourself and with precision, while trying to express something with your code...) tends to prefer other languages more adapted to get things right quickly and without too much thinking (because thinking about the hardware representation of your program at the same time as the high level representation is hard).
So, it's more like people who need efficiency will accept the power of c and c++ in exchange of their "complexity" (that is in fact dependent of the complexity of the software and the way it have been expressed) and other peoples who just want their windowed application done right and don't need all that C and C++ can offer as it's not the point.
For example, in videogame on console, you simply have no choice. On some embedded software, you have choice between C, C++ and Java but if you really need system resources access or speed, you'll not choose Java if you can.
So, to resume, the pitfall of C++ is that it gives you maybe too much power too bear, and in lot of case its more than you wanted. If i wanted to make a game that would be fast, i'd go c++ (and i do). If i want to make a management tool, i'd go a more high level language (C# for example).
[+2] [2008-12-22 01:32:32] Chris Johnston
The biggest pitfall of C and C++ is that the programmer has to manage everything. There is garbage collection, so every object that you dynamically create, you must also remember to destroy.
Other then that, both C and C++ are great languages and have their uses. Anyone who says that they are outdated/stupid/inefficient really doesn't know what they are talking about. Personally, I think every programmer should have to learn C at some point in their career and create an non-trivial application with it. Until you learn C, you really can't understand or appreciate any other language. In order to program efficiently you must understand things like dynamic memory allocation and pointers.
+1 This was the closest answer that related to the question.. Are there any other "pitfalls" that I should be aware of? - krebstar
BTW, isn't this garbage collection problem somewhat eased with RAII? I kinda don't understand yet why people make such a big fuss about it when you can simply overload the destructors to destroy the stuff.. - krebstar
krebstar: Somewhat, yes. But shared ownership is still kinda awkward to do with RAII and refcounting. And circular references can't be handled easily. A GC would do that trivially. - jalf
I see.. Thanks.. - krebstar
RAII means GC is an unnecessary overhead, and GC doesn't always handle some allocations - otherwise, why would you have weak references, handle wrappers and similar. Not to mention the big problem of lacking deterministic finalisation. - gbjbaanb
Use the Boost smart pointers (now in TR! and to be in C++09), and you'll be in good shape. Not all GC collects circular references. Remember that RAII is a more general solution than GC, since all GC does is memory. - David Thornley
[+2] [2008-12-22 17:01:13] FL4SOF
1 Pitfall: compiler dependencies - some features like RTTI, exception handling are not handled the same way across different compiers/platforms making it difficult to port.
cause: advanced features / lack of compatibility in old compilers ...
Alternative - i guess it is C++ specific :p
2 Code Bloat with STL - though there are ways to avoid it, it doesn't enforce them and every possibility of code bloat in real projects(though the design might be good).
cause: abuse of generic programming.
Alternative - not sure :(
3 Lack of Standard Unit Test Frame work - though there are many unit test frame works for C++ ( and many keep adding, with gtest being the latest one (as per my understanding) ) due to its very nature , it is hard to have proper Unit Test Frame work.
Alternative - JUnit and NUnit ...
+1 i think this is goood - krebstar
The cause for "Code Bloat with STL" is a lack of proper lambdas and auto keyword for types in C++. - J.F. Sebastian
[+2] [2009-03-19 23:40:38] Comptrol
There is a relevant discussion here:
C++ - Anyone else feel like C++ is getting too complicated? [1]
[1] http://www.velocityreviews.com/forums/t676282-anyone-else-feel-like-c-is-getting-too-complicated.html
Great link, the opening post is very good. - Matt Joiner
Hear Jeff Atwood's opinion [1] on this.
[1] http://www.codinghorror.com/blog/archives/000768.html
[+1] [2009-02-11 23:30:26] Eduardo León
Programmers hate C++ because it reminds them that programming is difficult. I mean, do we have to warp our brains around Boost templates all the time? Do we have to be told the difference between const and non-const (that's to not mention volatile) all the time? Why can't everything be non-const and that's the end of the problem? Oh, I see. When it's const, the compiler can perform some optimizations it can't when it isn't const. But, dammit, how does that reflect into something I can actually see, touch, smell, whatever? How many picoseconds of processor time am I saving by not using, say, Visual Basic and getting the thing done in 10x less time?
When I was at high school, I had a similar experience with grammar and syntactic analysis. The abstraction needed to parse those long sentences into subjects, predicates, complements, etc. was above what our little brains were willing to perform. It became worse when there were nested sentences ("I wish I had studied before the exam.", "She said she had done her homework when, in fact, she hadn't.", "The boy who ate her pie went away five minutes before she came."). It's the high school equivalent of programmers hating C++.
By the way, I happen to like C++. And I didn't dislike syntactic analysis when I was at high school, mainly because I was learning how to write (lame LL(1)) parsers, and I was excited with this language processing thing. But maybe that's because I'm an nerd with no life.
[+1] [2009-03-14 15:30:48] chris
What annoys me no end is that there isn't a singe string class. Half the time I spend converting strings from one type to another.
You name it { First ANSI X3J16 technical meeting 1990}:
(1) 1990, you're kidding right? it looks so late 70's. - call me Steve
(1) No, I am not. softwarepreservation.org/projects/c_plus_plus - Comptrol
[+1] [2008-12-22 05:08:01] skiphoppy
Well, I don't like C++ because it doesn't have the CPAN! My current regular language is Java; I'd prefer Java to C++ because (I believe) the JDK includes so many more standard libraries than C++. But I prefer Perl over that because CPAN has so many more libraries available on it.
When I want to write a program in Perl, I check out what CPAN has and build on it. If I'm wanting to do something with FTP, for example, there's a CPAN library (or two or three or four) to make it easy and let me focus on the unique part of my program, rather than opening socket connections and feeding it bytes. More importantly, there's CPAN libraries for things much more unusual and unique than FTP. You name it, somebody's taken a stab at it on CPAN.
In Java the situation is different. Opening FTP and HTTP connections is builtin, as is parsing XML (and HTML? can't remember). But if I have to go outside of what comes standard with the JDK, I'll have to look around the entire Internet rather than just one comprehensive archive that attempts to attract everything and even has private groups offering quality ratings. And despite the language being so much more popular and the fact that Java code is available across the entire Internet rather than just in one place, the fact is that the odds of finding a library to do what I want are usually lower in Java. Very often it's not that I can't find the library; it's that it doesn't exist. Or, rather, crappy implementations exist in thousands of companies, and they will never be released for everybody to pool their resources on and generate a high-quality version on which many people can build.
The situation in C++ is worse. You've got the standard template library (which I used in my shortlived C++ days), and you've got Boost (which I only know about in passing). And I'm sure there's other libraries out there. But there's less of it than even Java has.
I'd use C++ in a heartbeat if an employer made me a good deal on it. I'm not prejudiced against the language. But I do know that other languages have technical and cultural reasons that make modules, libraries, and extensions much easier and therefore much more plentiful, and I will always like that better.
So basically you're saying that C++ sucks because the libraries are not organized into one location/repository and there's few of them? - krebstar
I'm not saying that C++ sucks. I think it's a great language. I think Perl is better because for technological and cultural reasons there are more libraries and they are easier to find. I don't think it's the centralized location alone that has resulted in that. - skiphoppy
For the record, I thought C++ was pretty cool, and I've regretted not having more time to go back and play with it again. - skiphoppy
[+1] [2008-12-22 08:13:21] yesraaj
First everyone should admit that learning curve for c++ is really steep.People are in a hurry to use feature before learning it completely and correctly.
There is more than one way of doing thing in c++.So people stick with one they are good in,but when they come across others way it look little alien.
We tend to spend more time in learning language rather than with solving the actually problem.
We tend to write compiler dependent code with out even knowing it is.
When using pointer we should know about the low level things on the other hand we should forget the same while using high level containers like std::vector.
Undefined things in c++
good too, but could be more descriptive.. Perhaps expound on each item? especially about "writing compiler dependent code without knowing it is" or " when using std::vector, dont forget what particular characteristic of pointers?" - krebstar
for std::vector using iterator is better way than using vector_obj[0] even though that works.You cannot convert vector container with list when you do that kind of things. - yesraaj
we do not really need to know how this vector internally stores the element.If you get to know it you will end up using [] or trying to access the third item manually navigating thru the pointer's to first element - yesraaj
herbsutter.wordpress.com/2008/04/07/… - yesraaj
stackoverflow.com/questions/367633/… above link should be helpful - yesraaj
[0] [2008-12-22 10:55:05] A B
I spent 4 years learning/writing C++. Now I am mainly a .NET developer.
I generally avoid using C++ except when I am working on a module that is dealing with complex computations.
Also it is very un practical to deal with un managed code these days.
[0] [2009-02-05 12:17:07] Comptrol
There is nothing wrong with it , as long as you can learn a language from its Standard. The lack of ability to learn from Standard shouldn't be C++'s fault. It is Human Being's fault!
[0] [2008-12-22 15:27:45] Tim
The only thing I really wish for in C++ was thread support in the language. (But I suppose that is coming?)
yep, the Boost::thread library will (apparently) become the standard sometime in the future. Until then, its the de-facto standard. Or you can use Win32, TBB or OpenMP instead. - gbjbaanb
[0] [2008-12-22 13:24:14] Yuval F
Here's a book-length list of what is wrong with C++, called the C++ Frequently Questioned Answers [1]. I would not start a new project in C++ unless it was performance-critical. But if C++ works for you and suits your need, please feel free to ignore the previous sentences.
[0] [2008-12-22 04:09:32] Soviut
My main problem with C and C++ is that both force me to think like a computer, which I find is not conducive for solving a lot of high level problems quickly.
Simple, but I'm sure it's true for some people.. - krebstar
And we get a lot of lousy solutions to high level problems precisely because people are unwilling or unable to force themselves to think "like a computer". - Jon Trauntvein
[0] [2009-04-22 21:44:59] call me Steve
I find C++ quite cool.
One drawback: the lack of default (read STL [1]) powerful buffered I/O [2], especially compared to C#. Indeed you're free to optimize the bottleneck, but having it by default is great.
[1] http://en.wikipedia.org/wiki/Standard%5FTemplate%5FLibrary
[2] http://en.wikipedia.org/wiki/Input/output
[0] [2010-11-14 07:22:07] Matt Joiner
Templates are half-assed dynamic typing that occasionally provide performance advantages.
Boost tries to patch up the gaping holes in the standard library.
RAII is an attempt to address the worst side effect of exceptions.
3rd party lib, primitive types, manual memory management are all courtesy of C.
It's well known that explicit memory management is not faster than the best GCs.
The C++ standard library duplicates and is inferior to the corresponding C library. The only part of libstdc++ that C sorely needs is an equivalent to STL, albeit with better performance and debuggable. The rest should be tossed.
(1) You're mixing advantages and disadvantages here. This answer would benefit from a clear distinction. And your last point is simply false. The C++ standard library is much larger than the C library, only a tiny part of it is a duplicate (basically, only <string>, <limits>, <locale>, <new> and the IO streams, and the sort function) and most of that is clearly superior to C's libraries. Only the IO stream formatting is arguably inferior. - Konrad Rudolph
The problem is that C++ is a renowned-rapist:
According to researches, C++ programmers have Stockholm Syndrome [1]. Because, they first get raped by C++ itself during the learning curve, and can't abandon it aftermath!
[1] http://en.wikipedia.org/wiki/Stockholm%5Fsyndrome
[-1] [2009-03-14 15:02:02] Andomar
Have you ever seen a C++ program that never crashed?
[-1] [2009-03-20 00:04:06] lsalamon
C++ is soon as perfect as much as my ability and this is for any language.
[-1] [2008-12-22 01:49:52] community_owned
There are just other languages and platforms that make certain things trivial to do, that would require hours to do it C/C++.
But other things that can be easily done in C/C++ are themselves often painful in languages that feature higher levels of abstraction. This is becoming less frequent though as the newer platforms evolve and mature.
can you back that up with some examples? It would add more weight to your argument. - Simucal
Don't group C with C++. - Matt Joiner