
Re: [mongrel2] C versus C++ (2010) - shawndumas
http://librelist.com/browser/mongrel2/2010/7/15/c-verses-c++/#770d94bcfc6ddf1d8510199996b607dd
======
pmelendez
>" You have to do all the same memory checks, use valgrind, make sure you've
got destructors, and then that's made more complex by templates, object
lifecycles, exception rules, etc.. Frankly C++ doesn't have better memory
management than C, it just has more complex management."

I strongly disagree with the author, and I suspect he is biased for the "old
school" C++ (as he called it). For instance:

>make sure you've got destructors.

Objects allocated on the stack are guaranteed to be destroyed and hence their
destructors to be called. Which is very convenient if those objects are owners
of a resource (like a DB connection).

>"and then that's made more complex by templates, object lifecycles, exception
rules, etc.."

Object lifecycle are well defined but if all is an OOP problem not a C++ one.

As for the rest, the beauty of C++ is that if there is something that doesn't
apply to your project, then you don't use it. Your are not required to use
exceptions or templates if you don't want to.

> "Frankly C++ doesn't have better memory management than C, it just has more
> complex management"

Again, if you want to it can be complex, or it can be the same management you
would do in C. That's a flexibility that simply you don't have in C.

~~~
dkirkman
> Your are not required to use exceptions or templates if you don't want to.

This is absolutely true -- at least if you're working alone. But I've always
found the whole "let's use a subset of c++" to be untenable on long projects.
Somebody always joins that's infatuated with Alexandrescu, or some random
error handling strategy, and then you end up in endless debates about concepts
vs. abstract base classes. Those debates can be fun, but they seem to too
often leave behind hurt feelings and demoralized team members.

If you just throw back to c, all you have to deal with is the argument that
"we should really use c++, because <insert some random thing>". Those don't
last too long, you just have to respond that it's a c project :)

~~~
catnaroek
> endless debates about concepts vs. abstract base classes

Really? Generic programming's better static error detection facilities makes
it the superior alternative with respect to object-orientation, whenever you
can choose between the two. This pretty much settles the question IMO.

------
hdevalence
> You'll find crap in C++ like const *const char &, and hell if anyone knows
> what that really means since even though the pointer to a const to a const
> reference is consted to hell and back, oh look you can still increment it.
> They'd have been better off to just invent a new keyword:
> doesnotfuckingchange and stop there.

As I recall, Stoustrup originally wanted to call the const keyword 'readonly',
which is a more accurate description of what it does (const data is not
constant, it's read-only: something else can change it while you're not
looking, but you can't change it). They didn't, for compatibility reasons with
C.

That said, the const keyword allows you to move contracts about, e.g., "this
method does not alter its object", from the programmer's head into the code
where it can be checked by the compiler. (unless you have people doing stupid
things with mutable or const_cast).

But yeah, C++ has flaws. Big flaws [1]. Anyone who tells you otherwise is
probably uninformed or lying. The interesting question is, why do people keep
using it in spite of its flaws? Certainly a large part of that is inertia, but
I don't think that that's the only thing. I think there's a niche where
there's really not a lot of good options other than C++, and that's quite
unfortunate. But "C++ sucks" removes the possibility that there's anything
useful there, making discussion of better alternatives (e.g., would D work?
what is it about C++ that makes it useful? how do these languages compare?
etc.) impossible. See, for example, Rob Pike's complaint about why C++
programmers aren't all moving to Go, which essentially ignores a bunch of
reasons why you might use C++ (since Go is not a replacement for them). See
[2], [3].

[1]: [http://bartoszmilewski.com/2013/09/19/edward-
chands/](http://bartoszmilewski.com/2013/09/19/edward-chands/)

"I’ve been looking for a good analogy of what programming in C++ feels like
and I remembered this 1990 Tim Burton movie, Edward Scissorhands."

[2]: [http://blog.grok.se/2013/10/on-comparing-languages-c-and-
go/](http://blog.grok.se/2013/10/on-comparing-languages-c-and-go/)

[3]: [http://commandcenter.blogspot.se/2012/06/less-is-
exponential...](http://commandcenter.blogspot.se/2012/06/less-is-
exponentially-more.html)

~~~
catnaroek
> But yeah, C++ has flaws.

Stroustrup dixit: "Within C++, there is a much smaller and cleaner language
struggling to get out."

Rust?

> The interesting question is, why do people keep using it in spite of its
> flaws? Certainly a large part of that is inertia, but I don't think that
> that's the only thing.

Ownership management. Which has been expanded into full lifetime management
(including that of borrowed pointers) in... Rust!

Static polymorphism. Which is implemented in a crappy way in C++, but at least
is doable:

1\. Non-specialized templates: Type constructors.

2\. Concepts (sadly only in the heads of programmers): Type classes.

3\. Exported typedefs and type traits: Type families.

> See, for example, Rob Pike's complaint about why C++ programmers aren't all
> moving to Go, which essentially ignores a bunch of reasons why you might use
> C++ (since Go is not a replacement for them).

Dude must be completely deluded.

~~~
hdevalence
Yeah, Rust is really interesting, and something I'd like to try on a real
project. Hopefully I'll be able to do something with it this spring. But it's
certainly more appealing as a replacement than, say, Go, which I don't think
is really even that interesting as a language (but this is a personal opinion
which I'm not willing to argue about on the internet).

Rust also would immediately solve some things I find particulary annoying
about C++ (lack of sum types, inability to create new types that behave
identically to old types, etc).

One thing that I think would be nice to have in a hypothetical language is
vector support for integral types, the same way OpenCL has.

The Eigen library for C++ is IMO a really good example of the "Edward
C++hands" phenomenon. It's a terrific library, using C++ template magic to
produce optimized assembly for your platform, to achieve performance you just
can't get with C. On the other hand, it can be annoying to use, since there
are places where the C++ warts come out, and the developers have to put in an
extraordinary amount of effort just to get there. If you had this kind of
thing built into the language, it's much easier for everyone involved:
compiler authors, programmers, library developers, etc.

~~~
charlieflowers
That's cool. Do any of the new wave of systems programming languages offer
this kind of capability? D, Rust, Nimrod, etc.?

------
asveikau
There's plenty of reasons to prefer C over C++, but I don't feel like this
post is doing a good job of capturing them. I was much more amused by Linus's
version: [http://lwn.net/Articles/249460/](http://lwn.net/Articles/249460/)

IMO the most confused part of this post is to dismiss templates as "stupid". I
myself am rather "C-leaning" but I can acknowledge that some C++ features are
well thought out. Templates enable a lot of the "good C++" in a number of
ways.

My favorite example: for things like callbacks and lambdas. In C you often
find yourself using function pointers for this. With templates, you can make
that a compile-time cost instead of a runtime cost. So your callback can get
inlined right inside the caller. One practical result of this: things like
std::sort are faster than libc's qsort.

Similarly, he is right to say that exceptions can introduce memory leaks in
C++... But the C++ advocate's position would be that the RAII pattern avoids
this. And when you get into that habit, so long as you are consistent with it,
I can't say the whole thing is too bad. It's rather elegant.

Personally I think the problem is not C++ itself, rather that it asks a lot of
developers to be able to navigate towards the "good C++" and avoid the costly
anti-patterns. To make matters worse, people don't agree about what the "good
C++" is. IMO this is all more of a social problem than a technical one. Which
leads me into something similar to Linus's argument, to choose C to "keep the
C++ programmers out" \-- not that it's impossible to do C++ well, but that
there's a large community of people who are "doing it wrong", even if you can
agree what "right" is.

------
pcloadletter
Imagine C is like giving a wannabe tinkerer a knife; then C++ would be like
giving him a knife, blowtorch, dremel.

With the C guy, you more or less know what kind of damage he can do, and what
kinds of trouble he can get into. So you are able to look out for that.

The C++ guy, OTOH has exponentially more ways to cause damage.

Basically, both are tools, which, in the hands of a skilled artist, can do
wonders. But in the hands of the inexperienced (99%), C++ is a lot more
dangerous and complicated.

~~~
catnaroek
Not really. C++, at least modern C++, is a huge improvement in terms of safety
over C. The problem with C++ is that this improvement has been achieved in a
clumsy way: instead of providing clearly differentiated means of static
abstraction (e.g., non-specializable generics for parametric polymorphism and
concepts for ad-hoc polymorphism), we get templates, which have been equipped
with all sorts of corner cases (specialization, SFINAE).

------
aidenn0
Note that had mongrel2 been written in c++, I would not be working on it right
now. Not because I necessarily think it's bad, but because I don't know hours
to write good c++. there are all sorts of tricks to making c++ tractable[1]
and I just don't have enough familiarity with them.

1\. See for example RAII rule of three, etc.

~~~
skittles
I thought mongrel2 was a dead project. Are you working with it, or on it?
Nobody has committed any code in a long while.

~~~
aidenn0
we just cut a release candidate a month ago. I have lots of docs to update and
it's the holidays so it hasn't happened yet

------
film42
The whole time I was reading this I couldn't help think of all the "ported x
to 30 lines of javascript" headlines. By that I mean, just because it can be
done in a language, doesn't mean it's the best fit.

I think his best point was about dropping in boost. It doesn't make sense to
add more code, increase compile times, and complicated stack traces just to
use C++. I have to admit, I go out of my way to use newer tech sometimes even
though I know it'll slow me down. But, we (I) need to remember something about
Software Engineering -- at the bottom line, we're building software. Its
language and design should reflect the best possible result, and while that
doesn't always mean speed, it does mean using the best tools to solve that
problem.

~~~
eropple
When using modern compilers, the overhead for Boost is pretty minor. I get
that this was a big deal some time ago (I wasn't using C++ then, so I can't
say myself) but using Boost with clang and precompiled headers don't cause a
significant increase in compile times except in the case of a clean, which is
rare enough for me that I just use that as a chance to get up, move around,
etc.

Boost _can_ weird your stack traces a little, but they exhibit in predictable
ways that you can usually quickly reason out if you understand what your stuff
is doing.

------
bitwize
There is absolutely no reason not to use C++ in modern software development.

C++ gives you deterministic object lifetimes without the overhead of manual
management through the RAII pattern and smart pointers. It gives you
std::string, which is as easy to use, if not easier, than char*. It gives you
parameterized types and real value semantics for user-defined types. There are
even template versions of strcpy and friends which pass implicit length
parameters to strcpy_s and friends, which prevent a whole class of buffer
overflow bugs which have been the bane of C programmers since the language
came into existence.

With all the added safety and convenience that C++ gives you over C, it is
literally insane to use C where C++ could be used.

~~~
papaf
_There is absolutely no reason not to use C++ in modern software development._

Its nightmarishly complicated and gives you 1000 ways to blow your foot off,
and maybe one or two to get the job done properly. After about 18 years of C++
development I still go for C sometimes. C is a lovely language that is much
easier to learn. I cannot believe anyone would cheerlead for C++. Its a
necessary evil.

------
ridiculous_fish
I and my colleague ported a mature project (the fish shell) from C to C++,
over a period of about a year, so our experiences are relevant. Like many
projects, fish uses C++ as mainly a better C, without embracing exotic
templates, exceptions, smart pointers, boost, or other high-powered features.
Most of Zed’s points do not apply to this style of programming, and anyone
considering a port to C++ ought to consider it.

C++ as a better C does impose some costs, such as longer compile times, more
cryptic error messages, nastier backtraces, and losing compatibility with some
older systems. But these are tolerable, and on balance the benefits are worth
it. In one case, fish strayed and used shared_ptr, which caused compatibility
pain. This suggests we’ve hit a sweet spot, where if we adopted more C++
features we’d start to see a greatly increased cost.

 _Just using std::string would reduce the mm noise and make the code easier to
read and reduce the chances of memory leaks._

This is indeed what we found. The memory management simplification was a huge
deal, and that drove my decision for the port. However, the big win came not
from the specifics of C++'s memory management, but from its regularization:
imposing a single memory management scheme.

Like most C projects, the shell was rife with char _. When you see a char_ ,
you can't immediately know who owns the string, who is responsible for
deallocating it, and how it should be deallocated. std::string lets you reason
locally about the code, but so too do C libraries such as GObject, CFString,
etc. C++ won out over these alternatives because it's more widely supported
and has a deep pool of potential contributors. But the C++ "feature" that
mattered most was not that its memory management scheme was better, but that
it existed.

 _C is really the best because it is the lowest friction access to all the
POSIX stuff you need_

This is a big concern that disqualifies most other languages. For example, Go
or Haskell cannot easily do checks like `#ifdef VDSUSP`, and have no
guaranteed semantics for threads after fork. C is undisputed king here! But
C++ doesn’t impose much additional friction as long as you stick to the POSIX
primitives. e.g. pthread_* instead of std::thread or std::lock. There is no
“huge bother.”

 _The semantics of destructors are incredibly confusing, especially with
exceptions._

Destructors are indeed terrifying when in the direct gaze of a fully
operational C++ battlestation. However they are simpler in a suitably sane
subset of C++. The fish shell, for its part, disallows all exceptions, even
compiling with -fno-exceptions for a binary size savings.

 _No matter what, unless the language has a GC built-in, then C will have
simpler and more predictable memory usage._

As I argued above, the important aspect here is not the choice of language,
but the choice of memory management scheme. It is possible to make memory
management simple and predictable, or instead ad-hoc and haphazard, in both C
and C++. The key difference is that C++ comes with a scheme built-in (which
you may or may not choose to use), while C does not. I don’t know how mongrel
manages memory, but the “no matter what” claim is obviously wrong.

 _I couldn 't imagine trying to use the string output stream stuff to craft
messages and things._

Indeed: wstringstream is a big memory hog! But choosing C++ does not commit
you to using the stream formatting syntax, nor does it preclude using printf-
style formatting. fish uses printf-style formatting everywhere.

On the flip side, the simple task of appending two strings is awkward in C.
Either you have a fixed size buffer, or you commit to some string object type,
which then requires manual copying and cleanup. C++’s strings have flaws, but
they definitely simplify string handling compared to C.

 _Even something as simple as casting a float to an int is a pain in the ass
involving some weird template like syntax that frankly makes no sense._

C++ typecasts are mainly designed to support exotic template usage, and they
are indeed weird and onerous when using C++ as a better C (my pet example is
`static_cast<size_t>(-1)`). C++ programmers also promote the C++ casts as
“safer” or “better”, and characterize the C-style casts as “unsafe” and
“legacy.” Score one for Zed.

Leaving it off here, but I hope I showed how Zed’s points apply to using C++
in all its glory, and that “C++ as a better C” is totally viable for portable,
POSIX-using software.

~~~
pmelendez
>"Leaving it off here, but I hope I showed how Zed’s points apply to using C++
in all its glory"

All you said make sense but some points are still arguably. The thing is that
C++ feature set is big enough so any combination of them would probably be a
good fix for a given project.

For instance, you showed some advantages of using “C++ as a better C”, but I
had seen horrible bugs originated by a careless use of a void* that could be
prevented by using templates. So I would say that the experience change
depending of the project requirements.

Also, about the C++ cast style thing, it is verbose indeed but it is almost
like that on purpose, Stroustrup really wanted to discourage casting and in a
lot of cases I am agreed with him, most casts can be avoided.

------
coherentpony
Right. I don't see why we're having this discussion. You use C++ if you want
to deal with higher-level objects. The argument of, "memory management is
easier," is a total fallacy, just like has been pointed out in that list
message.

------
JSno
To me, I don't care this kinda debate. I just keep improving my C and C++
skills. Whatever language my manager wants to use. I just use it. (I can write
Python, Haskell and Java, C# too)

My personal favorite one is C though.

