I still say it doesn't suck

Somehow my last post ended up on Reddit after being dormant for 4 months. Well, I saw one comment in particular, which I'll quote here:

Oh by the way i would so have liked him to make a rebuttal of this instead of the hand picked stupid anti C++ trolls he has chosen in his article.

Had I consulted with the author of this comment before I wrote the blog post, that might have been possible. Instead, it was just a guy rebutting some of the common (and stupid) claims I see about why C++ sucks. But let's go down the list of points in that FQA since they brought it up:

No compile time encapsulation
Kind of true. Shipping C++ interfaces that contain implementation details to customers is a bad idea. You can always use the pimpl idiom for your publicly exposed interface.

Outstandingly complicated grammar
While the grammar is indeed complicated, this has very little to do with slow compile times and error messages. Almost all compile time / error message complaints come from template instantiations. If parsing is really that much of a problem (which I highly doubt), I guess you could wait until parsers start using SSE4.2 hardware string instructions specifically designed to speed up parsing. But yea.. I don't really think parsing is an issue at all.

No way to locate definitions
Alot of the discussion here is true, but has little to do with the issue of locating definitions. I'm not saying it's *easy* to locate definitions, it's definitely a complicated problem which is why few tools get it right. Visual Assist and Visual Studio 2010 (both only for MSVC) are both extremely accurate (and fast), and one could easily be fooled that they were using a module-oriented language based on the ease of locating definitions with these tools. So it's possible.

No run time encapsulation
This is a feature of the language. The author even points that out in the last paragraph. Not sure why this is here.

No binary implementation rules
Considering that C++ code should be able to run on arbitrary processor architectures (check out Fermi if you want a blown mind), I don't see how a consistent ABI is even a possibility.

No reflection
Lack of reflection is a hindrance sometimes, but I fail to see how this is a fault of the language. Does Haskell have builtin support for reflection? Not that I'm aware of (although I'm no expert), but I think it does have reflection libraries.

One could easily add reflection support to C++ by just putting a certain macro at the beginning of every class definition. The great thing about that solution is that it's selective - you only ever have to pay the overhead price of reflection when you need a class to be reflected on.

Very complicated type system
Although it's a simple example, it seems somewhat contrived to me. Nevertheless, it does kind of suck. In theory the problem could probably be solved with an appropriate copy constructor that just copies the vector's internal pointer but not the stuff it points to, but it takes some additional work on part of the library writer.

Very complicated type-based binding rules
I agree that the rules are complicated.

Defective operator overloading
This doesn't make any sense. It says that overloaded operators have to return their arguments by value, but this is completely false. The rest of the argument is null-and-void with rvalue references.

Defective exceptions
Another one that doesn't make any sense. a) Even if C++ exceptions are bad, what are you comparing them to? Java exceptions maybe? Those are TERRIBLE. b) RAII is trivial to get right. c) Any debugger worth anything can automatically break at the point of throw. Those that can't, you can always manually put a breakpoint in the constructor of your exception classes.

Duplicate facilities
I'm not sure how the new C++ methods of doing things are worse than the C counterparts. The only example I can think of off the top of my head is with printf/scanf, etc, but that problem is solved with C++0x and variadic templates. Any other occurences of the C++ counterpart being worse are probably related to excessive copying, which is also solved in C++0x with r-value references.

That being said, all of the old facilities in the language should be deprecated. But it's not exactly practical to do when potentially billions of lines of code depend on it.

No high-level built-in types
The initialization problems described have been eliminated in C++0x, and more complex initialization schemes can be created through clever (i.e. obtuse) template mechanics. there are already ways to initialize vectors with syntax such as vector v = vec_init(3)(4)(5)(6)(7);

Sure, it's not as nice as having them built into the language, but what's amazing about C++ is that the generic programming system is powerful enough to let you extend the core language in ways you never even thought possible and you can achieve very elegant syntax for doing things. Sure, it's complicated and ugly to read the machinery behind such techniques. But show me another language with the power to essentially re-define its own syntax that is easy to read in 100% of cases.

I'm not disagreeing that more built-in types wouldn't be nice, they would.

Manual memory management
Feature. Regarding the "owner" issue, it can now be expressed (by and large) with C++ syntax using r-value references. The issue of preventing access to dead access is addressed by the combination of boost::shared_ptr (which define multiple "owners") and boost::weak_ptr (which define multiple "observers").

Defective metaprogramming facilities
Hah! Templates are defective. They're a lot of things, but not sure I'd say they're defective. Difficult yes. If by defective, you mean "most powerful perhaps of any other language in existence" then I guess they're defective. With power comes complexity.

Unhelpful standard library
Unhelpful because it doesn't provide GUI facilities? come on, you have got to be kidding. This whole point is just full of nonsense. not all platforms support GUIs or network sockets. C++0x does have regular expressions. Matrix requirements are highly platform / application dependent. Do you want row-major or column-major matrices? Should they use SSE instructions if available?

Defective inlining
It sounds to me like he's admitting that the standard requirements for inlining in C++ actually aren't defective, despite the headline of the section, but rather that link-time code generation is still a relatively new technology.

I suspect this is one of those people that writes about how other people have never measured the performance of inline functions, yet has also not measured it. In other words, just looking for points to rant about but not being able to put his money where his mouth is. Many inline functions actually get compiled *to nothing*. That's the reason that you can have some complicated template mechanics that end up instantiating 800,000 template classes, which call 5,000,000 functions all over the place, and the generated assembly ends up being a couple of instructions. Did you know that if you try to inline a large function, the compiler often will refuse?

Implicitly called & generated functions
I suppose the alternative to implicitly generated functions is having objects be in an undefined state if, for example, you don't supply the constructor or assignment operator? Or maybe just having the program fail to compile, in which case author would complain that you have to add lots of boilerplate code just to get a class to compile even when you don't need it.

Maybe his problem is with the debugger he used. I've certainly never heard of the problem described here with seeing tons of assembly code in the debugger and having to manually reconstruct offsets.

That's it! I hope to see at least 400 new comments on the reddit thread now.


  © Blogger templates ProBlogger Template by Ourblogtemplates.com 2008

Back to TOP