views:

1714

answers:

16

I still feel C++ offers some things that can't be beaten. It's not my intention to start a flame war here, please, if you have strong opinions about not liking C++ don't vent them here. I'm interested in hearing from C++ gurus about why they stick with it.

I'm particularly interested in aspects of C++ that are little known, or underutilised.

Edit: People, please have at least a cursory read of other responses to make sure you're not duplicating what's already been said, if you agree with what someone else has said, upvote it!

+1  A: 

I think that operator overloading is a quite nice feature. Of course it can be very much abused (like in Boost lambda).

Filip
Operator overloading is not unique to C++.
Zach Langley
Also, operator overloading can be faked out in other object oriented languages, such as BigInteger.add(...). While it may look uglier, it has the same effect.
Raymond Martineau
I agree with Zach, but Raymond, I think that's coming into the "messy" category.
Jesse Pepper
Raymond: everything can be faked out in any Turing complete language. The whole point of operator overloading is the cleaner syntax.
Max Lybbert
Also, operators don't need to be member functions, so you can add an operator that works with BigInterger, even if you can't modify the source of the class.
KeithB
+5  A: 

Template mixins provide reuse that I haven't seen elsewhere. With them you can build up a large object with lots of behaviour as though you had written the whole thing by hand. But all these small aspects of its functionality can be reused, it's particularly great for implementing parts of an interface (or the whole thing), where you are implementing a number of interfaces. The resulting object is lightning-fast because it's all inlined.

Speed may not matter in many cases, but when you're writing component software, and users may combine components in unthought-of complicated ways to do things, the speed of inlining and C++ seems to allow much more complex structures to be created.

Jesse Pepper
How exactly does the speed of inlining allow for complexity? -1
postfuturist
It allows for complexity at runtime. If a component architecture does not have very lightweight, fast components, then only few components will be able to be combined before the system becomes unwieldy. I'm speaking from experience here.
Jesse Pepper
@steveth45 so are you going to +1 me back to zero?
Jesse Pepper
speed matters and c++ is the best at rescue!
dotnetcoder
+38  A: 

RAII / deterministic finalization. No, garbage collection is not just as good when you're dealing with a scarce, shared resource.

Unfettered access to OS APIs.

Shog9
+16  A: 

Deterministic object destruction leads to some magnificent design patterns. For instance, while RAII is not as general a technique as garbage collection, it leads to some impressive capabilities which you cannot get with GC.

C++ is also unique in that it has a Turing-complete preprocessor. This allows you to prefer (as in the opposite of defer) a lot of code tasks to compile time instead of run time. For instance, in real code you might have an assert() statement to test for a never-happen. The reality is that it will sooner or later happen... and happen at 3:00am when you're on vacation. The C++ preprocessor assert does the same test at compile time. Compile-time asserts fail between 8:00am and 5:00pm while you're sitting in front of the computer watching the code build; run-time asserts fail at 3:00am when you're asleep in Hawai'i. It's pretty easy to see the win there.

In most languages, strategy patterns are done at run-time and throw exceptions in the event of a type mismatch. In C++, strategies can be done at compile-time through the preprocessor facility and can be guaranteed typesafe.

You talk alot about the 'c++ preprocessor'. Do you mean the one that is equivalent/identical to the 'c preprocessor'? I'm pretty sure C and C++ are different languages, meaning the preprocessor is not unique to one language.
drhorrible
true... though I think it's a useful statement to make since many C#/Java devs don't know such joys.
Jesse Pepper
Anyone can appreciate that second point you're making.
Vulcan Eager
I don't know what the 3rd paragraph is getting at. The preprocessor knows nothing about types.
fizzer
Perhaps he has C++ templates in mind...
Roman Plášil
Yeah, I have a feeling that where he said preprocessor, he meant templates
Dan
@fizzer The third paragraph refers to the policy pattern: http://stackoverflow.com/questions/231318/a-strategy-against-policy-and-a-policy-against-strategy - C++ has two preprocessor runs actually; templating is the typesafe one, where #macros is the child that nobody likes. :)
mstrobl
A preprocessor runs before the compiler, and template handling is done by the compiler proper - templates have to be processed in various phases of compilation, for instance typechecking. So please stop this nonsense about two preprocessor runs. I downvoted the answer just for this.
Blaisorblade
+15  A: 

Write inline assembly (MMX, SSE, etc.).

Deterministic object destruction. I.e. real destructors. Makes managing scarce resources easier. Allows for RAII.

Easier access to structured binary data. It's easier to cast a memory region as a struct than to parse it and copy each value into a struct.

Multiple inheritance. Not everything can be done with interfaces. Sometimes you want to inherit actual functionality too.

Steve Rowe
+10  A: 

Shooting oneself in the foot.

No other language offers such a creative array of tools. Pointers, multiple inheritance, templates, operator overloading and a preprocessor.

A wonderfully powerful language that also provides abundant opportunities for foot shooting.

Edit: I apologize if my lame attempt at humor has offended some. I consider C++ to be the most powerful language that I have ever used -- with abilities to code at the assembly language level when desired, and at a high level of abstraction when desired. C++ has been my primary language since the early '90s.

My answer was based on years of experience of shooting myself in the foot. At least C++ allows me to do so elegantly.

Kluge
Downvotes...sigh. I guess I'm not as funny late at night as I think.
Kluge
I thought it was funny! And I consider a raft of downvotes on a satirical post to be a badge of honour. You earned my -1. :)
j_random_hacker
No-one wants to shoot own feet, so that doesn't count, I guess. But shooting own feet might become more common again with more powerful frameworks like Spring, if not used well. Sure it is easier with Spring than without, but with Spring it isn't automatically totally easy either.
Silvercode
Why would someone mark this as offensive?
Giovanni Galbo
I think the "offensive" flags are pushing it a bit far...
Rob
Making a funny post like this is often an example of shooting yourself in the foot. Ahh... the irony.
Kibbee
I thought it was hilarious!
Bob Somers
+7  A: 

I think i'm just going to praise C++ for its ability to use templates to catch expressions and execute it lazily when it's needed. For those not knowing what this is about, here is an example.

Johannes Schaub - litb
feel free to respond more than once :) Good answer
Jesse Pepper
"Haven't seen that in other languages yet." I haven't checked, so no idea if this is true, but D's template language may support this too. Besides that, probably some functional languages do as well, especially Lisp variants. For compiled imperative languages, your probably right (besides D maybe)
Dan
ah, indeed, i forgot about D. anyway i didn't mean no language support it, i said i haven't see it. maybe there is yet another one beside D that also supports it :) but i think no-one does it, and *also* has mostly source compatibility with C like C++ has.
Johannes Schaub - litb
+6  A: 

Absolute control over the memory layout, alignment, and access when you need it. If you're careful enough you can write some very cache-friendly programs. For multi-processor programs, you can also eliminate a lot of slow downs from cache coherence mechanisms.

(Okay, you can do this in C, assembly, and probably Fortran too. But C++ lets you write the rest of your program at a higher level.)

Boojum
+4  A: 

Technically, I think there's none, really!

I honestly don't think that there's anything that C++ can do which The D Language can't. No matter what ability C++ has, it's always harder and messier than D or any other language. Even a simple thing like a class declaration is so much harder and messier in C++ than any other language.

The only thing C++ can do is be compatible with millions of lines of codes already written in C++.
This is the only thing that no language other than C++ can do :)

hasen j
I was going to write main stream, or that C# and Java cannot, but i decided to refrain. I was specifically thinking of D when I thought about that. So fair point, though not an unexpected one.
Jesse Pepper
@hasen j: Multiple Inheritance?
dalle
@dalle Why do you feel that's a feature???
hasen j
haha yeah. Honestly though, I have never _needed_ multiple inheritance, though sometimes it allows me to be lazy. Usually, if I find myself thinking about using it, its a sign that I designed something wrong and I redesign to not need to - usually my code turns out better. Usually.
Dan
C++ has mostly source code compatibility with C, D hasn't. so there is one feature (one *very* important) that D doesn't have. also, like dalle says, multiple inheritance.
Johannes Schaub - litb
For all practical purposes, D does not exist at all. There are no D jobs, no D tools to speak of, no D books. Even as a hobby D makes no sense - I play with more interesting languages like Haskell or Scheme in my spare time.
Nemanja Trifunovic
Multiple inheritance has real uses. They tend not to come up all that much, in my experience, but they are there. Stroustrup designed C++ so you'd have all the sharp, finger-slicing tools you might need.
David Thornley
The reason I mentioned D is because there are a few things that mainstream languages (Java/C#) can't do but C++ can, but even things are so messy in C++, and the title of the questions says "What can C++ do that is too hard or messy in any other language"
hasen j
+4  A: 

C# and Java forces you to put even your 'main()' function within a class. I find that weird, because it dilutes the meaning of a class.

To me, a class is a category of objects in your problem domain. And your program is just a description of how these objects are manipulated by the computer.

In other words, your program is just your 'main()' function. Everything else, the classes and objects, is just details.

This is a simple, consistent model. However, C# and Java break this consistency by putting the program itself inside a class. This is analogous to a mathematical proof that for the most part uses symbols to refer only to things it's trying to describe and then suddenly springs up a symbol that notates itself -- the proof. That would be awfully confusing, if it were to happen.

Fortunately, unlike C# and Java, C++ allows global functions. That lets your main() function to exist independently of objects. This way C++, in my view, offers a more consistent expression of the object-oriented idiom and hence, this one of the things C++ can do, but C# and Java cannot.

Frederick
+22  A: 

I have stayed with C++ as it is still the highest performing general purpose language for applications that need to combine efficiency and complexity. As an example, I write real time surface modelling software for hand-held devices for the surveying industry. Given the limited resources, Java, C#, etc... just don't provide the necessary performance characteristics, whereas lower level languages like C are much slower to develop in given the weaker abstraction characteristics. The range of levels of abstraction available to a C++ developer is huge, at one extreme I can be overloading arithmetic operators such that I can say something like MaterialVolume = DesignSurface - GroundSurface while at the same time running a number of different heaps to manage the memory most efficiently for my app on a specific device. Combine this with a wealth of freely available source for solving pretty much any common problem, and you have one heck of a powerful development language.

Is C++ still the optimal development solution for most problems in most domains? Probably not, though at a pinch it can still be used for most of them. Is it still the best solution for efficient development of high performance applications? IMHO without a doubt.

Shane MacLaughlin
I especially like the comment about multiple heaps. You can do some very cool stuff with overloading new and delete, and using placement new etc in C++, very good!
Jesse Pepper
Jesse: Good point. I especially like using them for memory pooling for efficient object recycling.
Dan
Has any of you benchmarked those? A recent paper showed that most such allocators are not any faster and often slower than system ones.
Blaisorblade
@Blaisorblade, can you cite / link your references. I have profiled my specific application and found huge performance gains through allocator optimization. Note the perfomance gains are based around application specific typical use cases, it is not a general purpose optimization.
Shane MacLaughlin
+3  A: 

Passing POD structures across processes with minimum overhead. In other words, it allows us to easily handle blobs of binary data.

Vulcan Eager
This is not an exact duplicate but is along the same lines as what Boojum and Steve Rowe had to say about binary data.
Vulcan Eager
A: 

Tight control over system resources (esp. memory) while offering powerful abstraction mechanisms optionally. The only language I know of that can come close to C++ in this regard is Ada.

Nemanja Trifunovic
A: 

Well to be quite honest, you can do just about anything if your willing to write enough code.

So to answer your question, no, there is nothing you can't do in another language that C++ can't do. It's just how much patience do you have and are you willing to devote the long sleepless nights to get it to work?

There are things that C++ wrappers make it easy to do (because they can read the header files), like Office development. But again, it's because someone wrote lots of code to "wrap" it for you in an RCW or "Runtime Callable Wrapper"

EDIT: You also realize this is a loaded question.

Chris
the question said "too hard or messy"... did you see that?also, you say: "no, there is nothing you can't do in another language that C++ can't do". Read that again.In what way is it loaded? I'm looking for info from great C++ programmers.
Jesse Pepper
A: 

C++ provides complete control over memory and as result a makes the the flow of program execution much more predictable. Not only can you say precisely at what time allocations and deallocations of memory occurs, you can define you own heaps, have multiple heaps for different purposes and say precisely where in memory data is allocated to. This is frequently useful when programming on embedded/real time systems, such as games consoles, cell phones, mp3 players, etc..., which:

  1. have strict upper limits on memory that is easy to reach (constrast with a PC which just gets slower as you run out of physical memory)
  2. frequently have non homogeneous memory layout. You may want to allocate objects of one type in one piece of physical memory, and objects of another type in another piece.
  3. have real time programming constraints. Unexpectedly calling the garbage collector at the wrong time can be disastrous.

AFAIK, C and C++ are the only sensible option for doing this kind of thing.

Can you explain how "Unexpectedly calling the garbage collector at the wrong time can be disastrous."? preferably in this thread -> http://stackoverflow.com/questions/780815/surprises-moving-from-c-to-c/
acidzombie24
+3  A: 

This will probably not be a popular answer, but I think what sets C++ apart are its compile-time capabilities, e.g. templates and #define. You can do all sorts of text manipulation on your program using these features, much of which has been abandoned in later languages in the name of simplicity. To me that's way more important than any low-level bit fiddling that's supposedly easier or faster in C++.

C#, for instance, doesn't have a real macro facility. You can't #include another file directly into the source, or use #define to manipulate the program as text. Think about any time you had to mechanically type repetitive code and you knew there was a better way. You may even have written a program to generate code for you. Well, the C++ preprocessor automates all of these things.

The "generics" facility in C# is similarly limited compared to C++ templates. C++ lets you apply the dot operator to a template type T blindly, calling (for example) methods that may not exist, and checks-for-correctness are only applied once the template is actually applied to a specific class. When that happens, if all the assumptions you made about T actually hold, then your code will compile. C# doesn't allow this... type "T" basically has to be dealt with as an Object, i.e. using only the lowest common denominator of operations available to everything (assignment, GetHashCode(), Equals()).

C# has done away with the preprocessor, and real generics, in the name of simplicity. Unfortunately, when I use C#, I find myself reaching for substitutes for these C++ constructs, which are inevitably more bloated and layered than the C++ approach. For example, I have seen programmers work around the absence of #include in several bloated ways: dynamically linking to external assemblies, re-defining constants in several locations (one file per project) or selecting constants from a database, etc.

As Ms. Crabapple from The Simpson's once said, this is "pretty lame, Milhouse."

In terms of Computer Science, these compile-time features of C++ enable things like call-by-name parameter passing, which is known to be more powerful than call-by-value and call-by-reference.

Again, this is perhaps not the popular answer- any introductory C++ text will warn you off of #define, for example. But having worked with a wide variety of languages over many years, and having given consideration to the theory behind all of this, I think that many people are giving bad advice. This seems especially to be the case in the diluted sub-field known as "IT."

Troy Bergstro
Jesse Pepper
Ditto for the template argument, we use template mixins all the time (our frontend makes the syntax really concise to). It is *the* best form of code reuse you can get!
Jesse Pepper