

Readability Advantages of C over C++ - coliveira
http://coliveira.net/software/readability-advantages-of-c-over-c/

======
dkarl
_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.

------
mattgreenrocks
> 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.

~~~
rbanffy
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.

~~~
cageface
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.

~~~
Symmetry
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.

~~~
greyfade
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.

------
mv1
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.

~~~
loup-vaillant
> _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.

------
antubbs
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.

------
brimpa
_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>

------
zwieback
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.

~~~
supersillyus
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.

------
sn
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.

------
ignifero
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.

