Xenomachina

Saturday, May 08, 2004

C++ Rant

Blogs just aren't complete unless they include two things: blogging about blogging, and rants. I've already blogged about blogging a bit, so here's my obligatory "rant post".

The three programming languages I use the most are Python, Java and C++. All of these languages annoy me in one way or another. I often find that after using one language for a few weeks, I feel an incredible urge to switch to another one that doesn't have its flaws. Unfortunately, that other language will undoubtedly have its own set of flaws to deal with.

Of these three languages, the one that annoys me the most is C++.

The obvious complaint would be the lack of garbage collection. Garbage collection is hard to implement though, and the debate has been beaten to death already. There are lots of simpler things that could be done to make C++ a more bearable language.

First, there's the fact that one has to declare everything before its used. Are C++ compiler writers only able to figure out how to write single pass compilers? I'm sick of having to write "class Foo" all over the place and constantly rearranging my #includes.

Then there's the way methods, sorry, I mean "member functions", are non-virtual by default. This wouldn't be so bad if it weren't for the fact that you can overload a non-virtual member function in a subclass using a syntax that looks identical to overriding a virtual member function.

Another major frustration is the way C++ creates default copy constructors and assignment operators which are almost always incorrect. (they're virtually guaranteed to be incorrect any time you've got member variables which are pointers)

I'm also convinced that Stroustrup basically screwed up when he made operator[] one operator. Python has a much better approach. In Python, overloading of the subscript operator is done with two separate "magic" methods: __getitem__ and __setitem__. There's no need to "return a reference", because you always know whether you're being called as an lvalue or an rvalue. That means you don't end up with the stupid behaviour of STL's map where attempting to retrieve a non-existant element causes that element to come into being.

There are many other things that annoy me about C++, but the general flavor is that C++ always tries to make easy things hard, and hard things impossible. I think a lot of this might stem from Stroustrup not thinking very clearly about the problems involved. I used to think, despite the problems with C++, that Stroustrup must be a pretty smart guy. Then I went to a talk of his, Speaking C++ as a Native. If you look at the "Range" class that he uses in several of his examples, it's clear that he's confused. here's the class in question:

class Range {  // simple value type
  int value, low, high;  // invariant: low <= value < high
  void check(int v) { if (v<low || high<=v) throw Range_error(); }
public:
  Range(int lw, int v, int hi) : low(lw), value(v), high(hi) { check(v); }
  Range(const Range& a) { low=a.low; value=a.value; high=a.high; }
  Range& operator=(const Range& a) { check(a.value); value=a.value; }
  Range& operator=(int a) { check(a); value=a; }
  operator int() const { return value; }  // extract value
};
Who writes a range class that has three fields? I get low and high, but value??? It turns out that this class doesn't represent a range at all, but instead represents a value constrained to a range. I'm sorry, but I've seen preschoolers write more coherent code than this. If writing C++ "as a native" means writing code like you're hopped up on NyQuil, then I'll write it like a foreigner, thank you very much.
Being really good at C++ is like being really good at using rocks to sharpen sticks.Thant Tessman
i fully agree with you, thank you for your comments  
  Anonymous tarocchi on November 09, 2007
thank you very much for the great informations you share!  
  Anonymous automobile on December 21, 2007