
Popular Myths about C++, Part 3 - jabaldonedo
https://isocpp.org/blog/2014/12/myths-3
======
JoshTriplett
> “To understand C++, you must first learn C”

> “C++ is an Object-Oriented Language”

> “For reliable software, you need Garbage Collection”

> “For efficiency, you must write low-level code”

> “C++ is for large, complicated, programs only”

Well, 2.5/5 of those aren't myths. You certainly don't need to write low-level
code for efficiency, C++ does a rather poor job of acting like an OO language,
and you don't _need_ Garbage Collection, you just need to not manage memory
manually, for which solutions other than GCs exist.

You don't have to learn all of C to _write_ C++, but unfortunately you have to
learn C to understand _other people 's_ C++, because other people will not
restrict themselves to the subset of C++ you consider respectable. That's true
both for the C bits of C++ and for the obscenely complex corners of C++.

And C++ isn't just for large, complicated programs; it's for small,
complicated programs too.

~~~
nocman
"And C++ isn't just for large, complicated programs; it's for small,
complicated programs too."

hahahahahahaha!!!!!!!!!!!!!!!!!!! -- I was thinking that, but hadn't put it
into those exact words yet.

I was thinking something like "C++ is _definitely_ for complicated programs"
\-- not that they necessarily _need_ to be complicated, but that C++ often
unnecessarily complicates them.

I really _wanted_ to like the STL a long time ago, but I gave up eventually.
Happily my frustration with C++ led me to investigate other programming
languages (not that it was the only one I had used), and I write precious
little in it lately -- mostly just to modify code others have written in it.

~~~
yoha
I want to explain why you are getting down-voted: Hacker News don't like
onomatopoeias like “hahahahahahaha!!!!!!!!!!!!!!!!!!!”. In general, a neutral
tone is preferred and tongue-in-cheek is acceptable (like parent).

This is an important difference with most subreddits (some, like
/r/AskHistorian have a similar ambiance); it avoids ending up with long,
heated and shallow conversations.

~~~
nocman
I'm not exactly new here. I figured some might not like the "hahaha...", but I
don't really care. That's exactly what I did when I read the parent comment.

I didn't just leave it at the onomatopoeia -- I made a very reasonable comment
afterwards.

------
chisophugis
What Bjarne doesn't mention is the enormous difference in code size between
qsort and std::sort. The flexibility of having the compiler generate a sorting
routine from std::sort is convenient but enormously redundant in many cases.
In LLVM, we have array_pod_sort which is just a thin wrapper around qsort in
order to avoid the code bloat of std::sort:
[http://llvm.org/docs/doxygen/html/namespacellvm.html#ae5788f...](http://llvm.org/docs/doxygen/html/namespacellvm.html#ae5788f17f70ece4dcb34154325ce7126)

For example, the following generates about 2KB of instructions (and will for
basically every new type you want to sort):

#include <algorithm>

struct SomeStruct { int X; };

void foo(SomeStruct *SS, int NSS) { std::sort(SS, SS + NSS, [](SomeStruct LHS,
SomeStruct RHS) { return LHS.X > RHS.X; }); }

A qsort equivalent will only emit code for the comparator which is just a
handful of instructions.

C++ templates may be type safe and all, but at the end of the day they spew
duplicated code just as much as those header-only macro-based C containers and
algorithms; really more because it's less painful to write templates (vs.
macros) and so you do it more, and there is more stuff in the templates. So
even though in general the specialized generated code might be faster in most
cases (as Bjarne likes to tout), the overall hit on your code size (and
i-cache) can be dreadful. Currently, avoiding this issue in C++ just requires
diligence on the part of the coder (some optimizations like LLVM's mergefunc
can help, but in general it is a pretty hard problem and compilers are not
Sufficiently Smart (TM) yet).

~~~
btmorex
As long as std::sort can fit in the instruction cache, who cares? (outside the
embedded world obviously) It will always be faster unless you're getting
regular instruction cache misses.

~~~
makomk
Even if each instance of std::sort fits in the instruction cache, it's helping
to push some other code elsewhere in the program _out_ of the instruction
cache, slowing that code down in the process.

~~~
humanrebar
If std::sort pushes something out of icache, it's to make room for inlining
swaps and compares. I'm skeptical that the other things bumped from icache
should be kept hotter.

------
fiatmoney
"C++ is a big language. The size of its definition is very similar to those of
C# and Java."

I can't speak with authority to C#, but C++ is a _massively_ larger core
language than Java with far more complicated semantics.

~~~
magila
This is one thing I wish C++ advocates would stop bringing up. While it's
technically true that the page count of the C++ spec is comparable to that of
C# and Java, not all pages are created equal. The C++ spec is incredibly
dense, it's written in a very terse style and often packs as much information
into a single sentence as other specs spend an entire paragraph on. Also, the
Java spec in particular is typeset with much larger margins, a larger font,
and generally more vertical white space than the C++ spec making it seem
relatively bigger than it really is.

~~~
duaneb
Not to mention, the spec of Java has the benefit of being built on very firm
semantics, regardless of how well they were designed. C++ has no such solid
footing on which to stand.

------
comex
Bjarne should know better than to directly compare the performance of
std::sort and qsort. One is typically printed in full in a header file, while
the other is typically compiled separately. If qsort were found in a header
file, it could be inlined into identical code to the C++ version, regardless
of the fact that there are void pointers lying around everywhere.

There are caveats: the compiler might not choose to inline unless you force it
to, and if you do that then you'll end up with duplicate code in the case of
multiple calls with the same comparison function, while C++ can automagically
merge duplicates (although you probably want to write a wrapper function
anyway, and C++ will still waste _compile_ time generating the duplicates if
the calls are in different source files). Also, if the sorting function calls
a secondary function in multiple textual locations, and that function is
significant enough that inlining it would produce wasteful code, the pure
inlining-based approach will be insufficient (but I don't think most sorting
algorithms do this).

In other words, C++ makes it easier to do this sort of thing. No surprise! It
certainly makes it prettier. But when it comes to performance, in practice the
above would likely not be a big deal for qsort, so the difference between the
two functions is really more a matter of convention regarding the
implementation location. Benchmarking the two and explaining only that type
safety "makes for excellent inlining and good optimizations" is simply
misleading.

~~~
Aldo_MX
Does compile time really matter that much? I mean, unless you are building a
huge project which is expected to take hours to compile, I don't see much
benefit in optimizing compile times.

~~~
humanrebar
> Does compile time really matter that much?

Yes. Which is why C++ needs modules. It's a big problem when people have to
alter their designs to work around their tools (compilers, in this case).

~~~
Aldo_MX
Of course compile time matters when features like modules provide a
significant improvement.

My question was more focused in having to work around the compiler by doing
micro-optimizations, or avoiding some features that "may be heavy", just
because one project will take 65535ms instead of 65000ms to do a minimal
rebuild.

But at the end of the day, it really depends on the dimensions of the project.
In a huge project an improvement from 8 hours to 7.5 hours is greatly
appreciated.

------
ridiculous_fish
> I have never seen qsort beat sort

Well, here you go:
[https://gist.github.com/ridiculousfish/bb511993deba1d148317](https://gist.github.com/ridiculousfish/bb511993deba1d148317)

    
    
        qsort: 674 ms
        std::sort: 1104 ms
    

qsort only requires one invocation of the comparator to determine the order,
while std::sort often requires two. So qsort ought to be faster when
comparisons are expensive.

~~~
yongjik
I'm not sure why std::sort should require two comparisons. It's not required
to be stable (neither is qsort), so when comparing a and b gives (a >= b),
std::sort can just assume (a > b) and the array will be sorted just fine.

~~~
ridiculous_fish
Oops, you are correct and I was mistaken. std::sort does not need to determine
the total order in order to sort.

I would amend my top-level comment but I don't seem able to.

------
kgabis
That qsort example is getting tedious. I wonder why restrict keyword is never
mentioned when talking about C++'s performance advantages over C - it can
offer a huge boost on modern CPU architectures. I know it's supported by all
major compilers, but still - it's not a part of C++'s standard.

~~~
chuckcode
Completely agree. Restrict keyword can free up the compiler to vectorize a lot
of code with sse and avx on intel chips.

[1]
[http://locklessinc.com/articles/vectorize/](http://locklessinc.com/articles/vectorize/)
[2] [http://stackoverflow.com/questions/1965487/does-the-
restrict...](http://stackoverflow.com/questions/1965487/does-the-restrict-
keyword-provide-significant-benefits-in-gcc-g)

------
chuckcode
One of the reasons people use "low level code" for performance is because the
STL doesn't easily provide control of memory which is critical to performance.
Electronic Arts wrote their own version of the STL largely so they could
better control memory [1].

I'm not really sure about the rest of the myths. I'm a little confused about
how "To understand C++, you must first learn C” is a myth since C++ is a
superset of C so you kind of have to learn C.

[1] [http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2007/n227...](http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html)

~~~
ordinary
While the C++ language is indeed a superset of the C language, the paradigms
of modern C++ have almost no overlap with those of C. See for example the
string qsort vs string std::sort elsewhere in this thread.

The myth in "To understand C++, you must first learn C" is not that C and C++
are unrelated. The myth is that learning C helps you understand C++. The
reality is that telling people to learn C first is an excellent way of getting
them to write _really bad C++_ when they switch over to C++11.

~~~
ygra
I'd argue that UB is an evil enough concept in C that still exists and is
expanded on in C++ that _should_ be known by every programmer. Sure, paradigm
differences mean that idiomatic C code is not idiomatic C++ code, but knowing
the pitfalls of the language should be mandatory, imho.

------
stinos
_I used a container version of sort() to avoid being explicit about the
iterators_

Is that something new in C++14, coulnd't immediately find it on the net? Or is
it just a version he wrote himself? The latter makes sense for pretty much all
algorithms in <algorithm> which you'd use often on a container, to the point
you'd start wondering why the standard doesn't provide them built-in.

~~~
jeorgun
The C++17 standard should have them, once concepts become a thing; iirc
they're not in it now to avoid issues with choosing between sort(Container,
Comparator) and sort(Iterator, Iterator) overloads.

------
pavanky
The C greater function is unnecessarily long

    
    
      int greater(const void* p, const void* q)
      {
         return *(double *)p - *(double *)q;
      }
    

would work just as well.

EDIT: DON'T USE THIS, WONT ALWAYS WORK

~~~
_RPM
What is the point of defining the function with two void* arguments if the
cast will just take place anyway?

~~~
huu
The signature of greater is relevant because it has to conform to the
interface for qsort. See the final argument of the interface here:
[http://www.cplusplus.com/reference/cstdlib/qsort/](http://www.cplusplus.com/reference/cstdlib/qsort/)

------
jayvanguard
In 1995 C++ it wasn't a good choice. In 2000 it was a poor decision in most
cases. In 2005 it was a bad decision in almost every case. In 2010 it was
completely indefensible. It is almost 2015, why are we even talking about it?
C++ was a mistake. A bad detour on the highway of computing.

~~~
adamnemecek
So what's an alternative?

~~~
cheepin
"C++ sucks" has become a bit of a meme around here. The upsides outweigh the
downsides for a surprising number of cases. Every alternative is either
immature, doesn't solve the use case that needs C++ or doesn't have the
required libraries/tools.

~~~
cageface
There are people that sit back and bash C++ and then there are people that
just roll up their sleeves and build really cool things with it. I'd certainly
rather be in the second camp. I wouldn't mind having a simpler, more elegant
language with the same design tradeoffs but that language doesn't yet exist.

~~~
lomnakkus
False dichotomy. Plenty of people who "build really cool things with it" also
bash C++, and rightfully so.

~~~
cageface
Nobody I know. People I know that use C++ every day will admit it has issues
but are also realistic enough to understand that any language with the same
design constraints and long history as C++ will be complex.

It's the catbirds in the gallery that don't actually have to write the kind of
apps that require a language like C++ that "bash" it.

~~~
jevgeni
Catbirds like Linus Torvalds, for example?

~~~
rgbrenner
Does Torvalds write anything in C++?

The kernel and git are in C

~~~
jevgeni
This is my point exactly. I'd consider both git and the Linux kernel tough
projects, so the choice of the programming language is interesting. More so,
given his stance on C++.

~~~
inDigiNeous
How come it's interesting ? Linus has always been a C -programmer, and kernel
space is something where you want to keep things simple and access tha raw
bits of things, so C is a natural choice.

And if you've been programming C for 20 years or more, writing git with C
feels like a natural solution.

It's not always about writing stuff with the most high definition solution,
it's more about expressing ideas with the tools you know also.

~~~
jevgeni
In the case of git, C++ was actually evaluated (in a manner very natural to
Linus) and not discarded due to some habit:

[http://harmful.cat-v.org/software/c++/linus](http://harmful.cat-v.org/software/c++/linus)

~~~
yongjik
> I've come to the conclusion that any programmer that would prefer the
> project to be in C++ over C is likely a programmer that I really _would_
> prefer to piss off, so that he doesn't come and screw up any project I'm
> involved with.

Quintessential Linus, but I wouldn't call this an "evaluation"... :)

~~~
jevgeni
Fair enough.

As a side note: I think we as a community should promote the catchphrase
"You've Been Torvalds'd".

