
C++ Frequently Questioned Answers - kmavm
http://yosefk.com/c++fqa/index.html
======
DanielBMarkham
For those of you who are skimming: this is an attack job on C++

Instead of wading in to somebody else's religious war (and it's obviously
personal for somebody to spend so much time finding fault with _every_ item in
the original FAQ), I'll just say: works great in some situations.

I was building a shell extension for Microsoft Windows several years ago.
Booted up C++ and MVC, got up to speed on COM and shell extensions, and made
some magic happen. Once I got up to speed (which took some time) I found I was
just as productive in C++ as any other language. Same goes for a couple of
other projects I've done in C++.

C++ is my favorite language, and it's a god-awful power tool of a beast. I
don't use it regularly and don't plan to, but when you need it, it kicks ass.
Most of the time, however, you need other stuff, like fast development times,
ease-of-learning, common runtime, managed GC, and ease-of-understanding.
Criticizing C++ for not having those things is completely missing the point of
the language.

~~~
Hexstream
If x - (fast_dev_time + ease_of_learning + common_runtime + managed_GC +
easy_of_understanding) = kicks_ass, then what's x?

In other words, what redeems C++? What's the point of the language?

~~~
mojuba
C and C++ (and a couple of other languages like Delphi) provide naked,
unprotected pointers, which implies almost full control over memory and the
CPU that no higher-level language can give. With pointers you are closer to
hardware, in other words.

On top of that, C++ has damn powerful meta-language facilities no other
language of any level has, which are, however, beneficial only when in good
hands. It's too easy to misuse C++ unfortunately.

~~~
Hexstream
I agree with your first point.

However, I'll have to very strongly disagree with "C++ has damn powerful meta-
language facilities no other language of any level has". C++ actually has
terrible support for meta-language facilities.

It is inconceivable in my mind that C++'s support for that is anywhere near
something like Common Lisp, so forget about it being the best in that respect.
I'd love to know what parts of C++ are great meta-language facilities. If you
say C++ macros I'll have to laugh. Hard.

</smuglispweenie>

~~~
mojuba
Templates, the implicit ctor/dtor paradigm coupled with scoping, to name a
few. I know Lisp has a unique feature - let's say, unity of code and data, but
hey, there are plenty of languages with unique features not found in C++;
nevertheless I think my statement still applies, that no language compares to
C++ in terms of power of meta-language facilities. I think I understand Lisp
and I'd be happy if we could avoid Lisp wars in this context.

~~~
anamax
Templates, the implicit ctor/dtor paradigm coupled with scoping, to name a
few. I know Lisp has a unique feature - let's say, unity of code and data, but
hey, there are plenty of languages with unique features not found in C++;
nevertheless I think my statement still applies, that no language compares to
C++ in terms of power of meta-language facilities.

Umm, lisp macros can implement all of C++ meta-language facilities and more,
so how are said meta-language facilities more powerful?

And then there's the meta-language protocol....

~~~
mojuba

      {
        X x, y;
        if (x > y)
          return;
        // some code ...
      }
    

where X has a destructor. I'm curious if you can do this in Lisp without
explicitly calling the destructors (for x and y) in proper places - two places
in this example.

~~~
anamax
unwind-protect handles this case. (Note that most lisps have GC so if freeing
memory is the only reason you're calling the destructor, you don't need to do
anything.)

[http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec...](http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/speope_unwind-
protect.html)

There's a reason why PG refers to non-lisps as "blub".

[http://www.gigamonkeys.com/book/beyond-exception-handling-
co...](http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-
and-restarts.html) <http://www.lisp.org/mop/index.html>

~~~
mojuba
unwind-protect is not the same. Destructors in C++ are part of custom data
types, and unlike unwind-protect, they are "implied", which makes your code
safer and more succinct. And no, it's not necessarily memory clean-up, of
course.

C++ destructors are a powerful tool, you can create data types that otherwise
would require support on the compiler's side.

~~~
anamax
> unwind-protect is not the same.

You're right - they're more powerful, but bringing that up didn't seem
necessary.

> And no, it's not necessarily memory clean-up, of course.

Never said that they were. However, C++ programmers spend a fair amount of
time worrying about/writing code for memory cleanup and destructors is where a
lot of that time/code goes.

Folks using languages with GC don't do that nearly as much.

Destructructors are only implied for scope-allocated variables. By tying value
lifetime to variable scope, C++ gets to do certain things, but as a result,
programmers have to do certain work.

Lisp values are not tied to variable scope, so complaining that lisp doesn't
have mechanisms for values that are tied to scope is sort of like complaining
that a hovercraft doesn't have a parking brake.

> C++ destructors are a powerful tool, you can create data types that
> otherwise would require support on the compiler's side.

Actually, they're just a mechanism for calling code when a value "goes away".
That's almost required for a language with manual memory management but
unnecessary for languages with GC.

However, destructors are also the only way that C++ has for automatically
calling code. Other languages have other, more general, mechanisms.

~~~
mojuba
I see what you are saying, but unfortunately garbage collectors in their
present form are more evil than good. They are fine in some situations, but
may turn to a problem in others. For example, you may get very undesirable
effects if you are creating and destroying a large number of objects in a
time-critical application (a game, etc).

So, languages that provide no way of controlling allocation have relatively
limited application compared to those that do provide full control over memory
allocation.

By "relatively limited" I mean just relatively, that is, the reason Python,
Ruby, Perl, PHP, Java, C# and Lisp with their GC facility exist is that it
works most of the time, but there are certain areas where you have no choice
other than C/C++. Kernels, compilers (including Lisp compilers), game engines,
everything that deals with hardware, image, audio and video processing, etc
etc.

This is an endless list where you really have no choice. Try to write a VST
plug-in in Lisp, for example, that would add a reverb and will be able to do
it on 8 audio channels in real-time on a 3GHz CPU.

~~~
anamax
> I see what you are saying, but unfortunately garbage collectors in their
> present form are more evil than good.

Wrong

> They are fine in some situations, but may turn to a problem in others.

Correct.

> For example, you may get very undesirable effects if you are creating and
> destroying a large number of objects in a time-critical application (a game,
> etc).

Not if you're using a reasonable real-time GC.

If allocation and reuse is occuring, memory management code is being executed.

GCs tend to run a bit slower, but you get faster development. Sometimes that's
a good trade, and sometimes it isn't. (My real-time friends are correct when
they say that late answers are wrong answers. However, it's also true that
wrong answers are wrong answers.)

> compilers (including Lisp compilers)

Wrong again.

> everything that deals with hardware, image, audio and video processing

Wrong again. (Yes, lots of such systems are built with C/C++ but folks have
done them with GC languages.)

And, our python friends have figured out that one can use C/C++ as an
extension language for the heavy processing, where very little memory
management occurs, and python everywhere else, getting the benefit of both
worlds.

This is important because, when you get down to it, most of the applications
that have lots of signal processing and the like are actually a couple of
time-critical small kernels surrounded by lots of other code. Said other code
dominates development time so GC for it is a big win.

> game engines

Yes and no, because "game engine" covers a wide range of things (from physics
and rendering through high level "AI") and it depends on the available
processing power.

------
kmavm
The author, Yossi Kreinin, is also one of the most underrated bloggers about
software implementation on the planet. Before dismissing him as a one-trick
pony language bigot, please sample <http://www.yosefk.com/blog/> a bit.
[http://www.yosefk.com/blog/extreme-programming-
explained.htm...](http://www.yosefk.com/blog/extreme-programming-
explained.htm..). is just waiting to be dusted off and resubmitted by some
enterprising young news.yc karma junky.

~~~
gcv
Fascinating that Yossi Kreinin hates Boost libraries so much. I have had my
share of problems with them (slooooooow compilation and horrible template
compiler error messages, mainly), but the Boost.Spirit parser library turned
out to have been a lifesaver. I needed to parse JSON in a C++ system, had
Boost available, but could not realistically install any other external
library dependencies. Well --- the TinyJSON
(<http://blog.beef.de/projects/tinyjson/>) looks a little funky thanks to all
the templates and operator overloading magic, but it works well and I dropped
it into the system as a header file. Problem solved.

I'd make heavier use of Boost.Filesystem, too, but I'm stuck deploying with an
older version of Boost which lacks a few essentials. I never understood the
messiness of concatenating path strings by hand until I was forced to stop
using os.path (Python) and java.io.File (Java, Clojure).

~~~
kmavm
Templates taking too long to compile and producing ridiculous error messages
is actually one of, if not _the_ , major complaints Yossi has about C++,
though. One of the rarely spoken of differences between C and C++ is that the
latter has a ludicrously slower compile leg of the compile/edit/debug cycle,
and once you start digging into it, the slowness of compilation is built into
the language (basically, matching template specializations is computationally
hard), and is not an artifact of so-called "poor implementations."

------
joey
It's probably more important to have a good set of coding guidelines when
writing C++ code than with other languages, but there's no reason not to write
new projects in C++ if it's the best language for the task and team.

Voxli is built on C++ and boost. We make liberal use of scoped_ptr and
shared_ptr where appropriate and we have yet to experience resource leaks in
our client.

~~~
dryicerx
This.

Actually to add to your comment, it's not just good, but a MUST to have a set
of good coding guidelines. The language is complex for a reason, you tell the
Compiler EXACTLY what you want it to do, and this takes away overhead from the
compiler trying to guess. It's a trade off between the convenience to the
programmer to the performance of the application.

C++ isn't perfect, it's not meant for everything. But for fast, large, and
complex systems, C++ is one of the best ways to go about it.

~~~
kowsik
C++ is so not perfect and is definitely not for large scale development. Read
this: <http://labs.mudynamics.com/2007/07/23/writing-c-within-ruby/>

~~~
nickpp
Reality, however, contradicts you. C++ is one of the only languages out there
PROVEN in the field by being used in thousands of large-scale developments.

Operating Systems, Office applications, Browsers, Search Engines, etc. -
aren't these large scale?!

~~~
stonemetal
Linux C, BSD C, really I can't think of a truly large stable system written in
C++. There are plenty written in C.

Edit: Thanks, I didn't know there was a C++ OS out there. Though to be fair to
C++ it hasn't been around as long nor been as stable as C (from C with classes
to C with classes exceptions and templates.)

~~~
andrew1
Symbian OS is written in C++, excluding some internals of the kernel written
in C/ARM assembly. I was told when I worked there (3-4 years ago) that the
entire code base (including test code, variant code etc.) is on the order of
50 million lines of code. So definitely large. Stable? A matter of opinion.

------
rmaccloy
Also worth reading (edit: if you've got an hour to kill and care about the
subject):
[http://groups.google.com/group/comp.lang.c++.moderated/brows...](http://groups.google.com/group/comp.lang.c++.moderated/browse_frm/thread/870d15c57e831fc5/5868fd6e57f6ae2c)

The author defends his position pretty coherently and civilly; you can
disagree with his conclusions but calling him a troll or an idiot is certainly
not warranted.

------
DarkShikari
On a quite related note, I like this page as well:

<http://harmful.cat-v.org/software/c++/I_did_it_for_you_all>

;)

------
Confusion
If you're criticising something as vast as the C++ FAQ lite and find issue
with _every single claim_ , then you are bigoted and your review probably
isn't worth it.

~~~
rmaccloy
This is both a bad argument and kind of lacking a sense of humor, since
programmers do this (point by point rebuttals) _all the time_ (see: every
popular thread on the LKML, ever)

~~~
Confusion
Even if programmers do something all the time, that doesn't mean it's right.
The reason is simple: every opinion has arguments in favor of it. If someone
offers five arguments in favor of an opinion, usually at least two are
reasonable. If someone attempts to rebuke all five points, they're usually
being unreasonable. It's also counterproductive, because bad counter-arguments
call for counter-counter-arguments, which detracts from the actual points
under discussoin. If you think an argument isn't persuasive and doesn't have
much weight, then _that_ is what you should say, instead of searching for some
nitpicky way to counter the argument, usually ending up in discussions about
semantics because you actually agree on the point.

As for this article: if this was intended to be humorous, then it contains far
too much that seems to have been intended seriously, for my taste. After a few
points he could have stopped beating the dead horse.

Wrapping criticism in humor is an annoying strategy similar to the 'poisoning
the well' fallacy: as soon as someone tries to start a discussion, you can go
"where's your sense of humor?" and your humorously wrapped argument remains
unchallenged. That gets under my skin and may have impaired my humor detecting
capabilities here.

~~~
rmaccloy
I don't think your first paragraph follows (I think you can certainly contest
every assertion in favor of a position without being illogical), although I
agree the style is usually unproductive. I'd rather not get into debating it
here, though.

The 'humor' I was referring to wasn't in the article (which is pretty bland)
but in the fact that hey, this fits the stereotypical image of a programmer:
slightly OCD (nitpicky) and lacking social grace. You'd think we'd be used to
it :)

------
spectre
Wish there were more sites like this. We mostly just believe the answers we
recieve.

------
sreque
I feel like people miss one of the main points of this FQA. The author
repeatedly asserts that most people who think they need C++ do so because they
think they need the performance it can offer. Most of these people, however,
don't actually need the extra performance and would be much better off with a
higher level language. Those that actually do need the performance and know
what they are doing would be better off just using C with assembler.

In many ways, I think he is right. C++ tries to be high-level, low-level and
everything in between all at once, and the end result can bring a lot of
potentially unnecessary frustration to programmers. There are several
projects, such as LLVM, for example, that get by using a "tasteful subset" of
C++, and I would be interested in learning what that subset is.

------
timr
_"Unfortunately, you can't tell the class of a C++ object given a pointer to
it at run time....which is why you can't automatically collect the garbage of
C++ programs."_

What nonsense. Here's what I learned from this link: trolling isn't as
effective when it requires the trollee to read 10 pages of text.

This is garbage. Please flag it for collection.

~~~
DarkShikari
Just because you disagree with something does not automatically make it a
troll.

~~~
dave_au
AFAIK it's reasonably well known as an unintentional troll - there was a
stackoverflow question about the FQA (still looking for the link) that
basically mooted almost every point.

I was reading it as a neutral party, however some very knowledgeable C++
appeared to convince all comers that the FQA is either based on ignorance or
is disingenuous.

~~~
finnw
I also once tried referencing the C++ FQA on stackoverflow and was quickly
downvoted. Maybe SO is just the wrong place to mention it, probably because of
a C++ bias from the high percentage of SO users who develop on MS platforms.

