Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Readability Advantages of C over C++ (coliveira.net)
29 points by coliveira on May 31, 2011 | hide | past | favorite | 17 comments


> It is not a surprise that large scale projects such as the Linux kernel use C without any problem.

I'm sorry, but a post that lacks intellectual honesty when discussing a rather complex topic such as this one just shouldn't make it to the HN front page. If you cannot bring yourself to at least admit in passing that increased expressiveness of a language can be beneficial in some situations, then I'm not even sure what to tell you. Your post is not weakened by admitting this, but I feel like the perception is that you must take a hardline approach.

As I've said before, these sorts of blog posts skate by simply because they tell HN what it wants to hear without actually contributing anything new to the discussion. Thus, it is bikeshedding, and, ergo, not 'highly interesting' (per pg's guideline). Additionally, this topic comes up repeatedly, and I'm not certain why it needs constant discussion.


I understand your point on increasing expressiveness, but how far do you need to go into post-incrementing C before you decide you'd better use a language made with the specific purpose of supporting such expressiveness rather than bolting it on top of C.


Unfortunately there are still many problem domains where you absolutely require the low-level control of memory and execution time that C and C++ provide. In most of those domains the extra expressiveness of C++ is a big win, despite its many warts.

Could you, with hindsight, design a better low-level language than C++ for these tasks? Yes. Is such a language available today? No. People write things like Photoshop and Cubase and Maya in C++ for a reason.


I think the contenders here are Google's Go, Mozilla's Rust and for an academic longshot BitC.

Thus far, Go is the most mature & has the most traction, but is still very much in its early days and a minority sport. Outside of Google, the most ambitious use of Go in production is Heroku's Doozer.

There are those who would say D should be in my list above. However the D community seems to be fatally divided and D has failed to get sufficient traction despite being around for quite a few years.


http://www.bitc-lang.org/ Not there yet, but I'd say there's hope.


Isn't D exactly what you're looking for here? That is, roughly equivalent to C++ but with a coherent design?

I head Go also lets you manage memory manually if you want to.


D somewhat lacks stability. The language is still maturing and there was, for a long time, a major split in which standard library was... standard (and even now, that question isn't really clear). There's also the issue of tools - there are only two D compilers I know of, and neither of them is that great (and GDC is buggy, IME). It's also got several warts of its own.

When D matures a little more, maybe. At least C++ has a stable standard lib.

That's why I'm holding off on using it, and (with the exception of the standard lib) probably why most people are holding back.


A "fun" exercise in C++ is to take a line of code that makes extensive use of advanced features, like templates, smart pointers, etc. and step through a -O0 compile with gdb. I was shocked, in some cases, about how many different functions were called for what looks like a simple expression.

This can lead to some interesting errors. For example, writing

void foo(const std::string s)

by mistake, instead of

void foo(const std::string &s)

won't result in a compiler error, but will result in an unusually large, and unexpected overhead in calling foo.

On the other hand, STL is great (less the error messages). I sorely miss it when programming in C.


> I sorely miss [the STL] when programming in C.

Well, C++ got at least one thing right: deciding to support parametric polymorphism (or "genericity"). Templates are quite ugly, but at least they do the job.


It seems like the thesis is that C++ is a more complicated language, and therefore the code produced in it is more complicated and harder to comprehend. This line of reasoning is specious.


For example, operators can be overloaded, so that many math operations, and even punctuation such as “,” can be overloaded by programmers.

',' is an operator too, not just punctuation.

http://en.wikipedia.org/wiki/Comma_operator


Maybe the results of a function call may not be completely understood by the programmer, but from the syntactical point of view it is easy to figure out what is going on in the program.

And, to put it clearly, the problem is not that the function or class is doing something we don’t know. The problem is mostly in trying to figure out what is happening in a given line of code. In C is very easy to figure out what is being called (up to macros): just read the manual for the functions being used and you will have a good idea of what is being executed.

After sorting through this pile of caveats, what point remains?

In C++, on the other hand, a large number of things can be happening in a single line: an overloaded operator, a type conversion, a template instantiation, an overridden function in one of a dozen of classes, a constructor called in some part of the hierarchy, in some namespace…

It isn't that hard to figure things out in C++. An operator is an operator is an operator; there are a fixed list of symbols that can be used as operators. An operator may be defined by the language, or it may be user-defined. Template instantiations are visible. (I don't recall whether you need <> when a template has default parameters, but in that case it just acts like a regular class anyway.) Constructors are just functions that get called when objects are created. Granted, you can create a confusing situation by using multiple inheritance, but multiple inheritance is one of C++'s nuclear options, like macros in C. (I suspect the author would blame C++ for having multiple nuclear options instead of just one.)

Namespaces are very nice for organizing code, and almost every language has some equivalent mechanism. I think the burden is on the author to argue that everyone else is wrong about this.

I'll give him type conversions. Those can be tricky and unexpected, and it's backwards that you have to declare your constructors "explicit" to prevent them from being used in type conversions. It should be the other way around; you should have to declare constructors "implicit" in the rare cases where you want to enable conversion. However, once you're paying attention (and I agree you shouldn't have to), it isn't difficult to figure out when type conversion is happening, simply because you'll see that an argument of a certain type is being passed to a function that cannot take that type. If it compiles, then a type conversion is being invoked. Where people get really confused is when they're trying to take advantage of type conversion, but the conversion they think is happening isn't actually happening. Personally, I've rarely messed with it, so I don't care.

You have to be smart enough to figure out what is going on

I can't tell you how much it hurts my head to read C or how many times I've thought I just wouldn't be smart enough to be a C programmer. It's a different kind of thinking. I'd much rather read a few hundred lines of C++ full of tricky constructs than a few thousand lines of C full of buffer allocations and deallocations and return value checks. My brain overflows and I can't keep track of the high-level shape of the code. Trying to figure out how C code works when I don't already know its purpose is very hard for me. To each his own, I guess.


This article sounds like a lesser version of a Linus rant I read once and even he used the strawman argument of "in C you can always see what's going on". Does nobody in C use function pointers?

I say horses for courses and if you use operator overloading and templates to make your C++ code overly cute then it's not the fault of the language.


C++ can be quite readable, but C can't be particularly magical. If I were Linus and I spent my days reviewing patches from all sorts of folks to a very large codebase, I'd be inclined to prefer a language that can't do anything unless you ask for it.


Try reading the linux kernel. A beautiful example of object oriented c, but it's not any easier to read than c++.


Readability depends on the writer, and if someone is trying to duplicate the functionality of C++ in C I expect they're liable to do a worse job than using C++ directly. void* pointers are one example of why.


The usual complaint about C++ is the misleading compiler errors when one uses the STL. I disagree there are other readability issues. Encapsulation and polymorphism exist precisely because you don't want to know what's underneath. It goes without saying that overusing operator overloading is bad design, not just a readability issue.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: